【问题标题】:Execute a func when the device time change当设备时间改变时执行一个函数
【发布时间】:2019-01-20 15:31:08
【问题描述】:

我正在尝试在设备时钟更改时执行一个函数。 这个函数将返回一个学生的下一门课程,所有课程都在一个数组中。

如果我理解正确,我们无法在设备时钟更改时执行函数。 我读过一些主题,人们说要进行 60 秒或其他时间的计时器,但如果用户在 08:05:07 启动应用程序,则函数将在 7 秒后执行。 我想使用一段时间,但我认为它会大量使用 CPU,因此也会消耗电池。没有?

有人有想法吗?

【问题讨论】:

    标签: ios swift time timer


    【解决方案1】:

    如果你只是说你想在某个特定的未来Date 触发一个计时器,你应该只计算从现在到那时的时间量(使用timeIntervalSince),然后使用它。

    比如现在是“2019-01-20 17:11:59 +0000”,但是如果我想让它在17:15开火,你可以这样做:

    weak var timer: Timer?
    
    func startTimer() {
        let futureDate = ISO8601DateFormatter().date(from: "2019-01-20T17:15:00Z")!
        let elapsed = futureDate.timeIntervalSince(Date())   // will be roughly 180.56 in this example at this moment of time
    
        timer?.invalidate() // invalidate prior timer, if any
    
        timer = Timer.scheduledTimer(withTimeInterval: elapsed, repeats: false) { [weak self] _ in
            // whatever you want to do at 17:15
        }
    }
    

    显然,但是您提出的futureDate 在您的情况下会有所不同,但它说明了这个想法。只需计算未来目标日期和现在之间经过的时间,并将其用于计时器。

    现在,如果你真的担心时钟的变化,在 iOS 中你可能会看到 significantTimeChangeNotification,例如,

    NotificationCenter.default.addObserver(forName: UIApplication.significantTimeChangeNotification, object: nil, queue: .main) { [weak self] _ in
        // do something, maybe `invalidate` existing timer and create new one
        self?.startTimer()       
    }
    

    我想使用一段时间,但我认为它会大量使用 CPU,因此也会消耗电池。没有?

    是的,循环旋转,等待一段时间过去,总是一个坏主意。通常你只需设置一个计时器。

    这个函数会返回一个学生的下一门课程,所有的课程都在一个数组中。

    这引出了应用程序是否会在前台运行的问题。如果您想在未来某个时间通知用户,无论他们是否正在运行应用程序,请考虑“user notifications”。例如请求通知权限:

    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in
        if !granted {
            // warn the user that they won't be notified after the user leaves the app unless they grant permission for notifications
            DispatchQueue.main.async {
                let alert = UIAlertController(title: nil, message: "We need permission to notify you of your class", preferredStyle: .alert)
                if let url = URL(string: UIApplication.openSettingsURLString) {
                    alert.addAction(UIAlertAction(title: "Settings", style: .default) { _ in
                        UIApplication.shared.open(url)
                    })
                }
                alert.addAction(UIAlertAction(title: "Cancel", style: .default))
                self.present(alert, animated: true)
            }
        }
    }
    

    然后,假设已授予权限,然后安排通知:

    let content = UNMutableNotificationContent()
    content.title = "ClassTime"
    content.body = "Time to go to math class"
    
    let components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: futureDate)
    let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
    let request = UNNotificationRequest(identifier: "Math 101", content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request)
    

    【讨论】:

      【解决方案2】:

      我这样做了

          private var secondesActuelles : Int = 0
          private var timer = Timer()
      
          private func récuperLesSecondes(date : Date) -> Int {
              let date = date
              let calendar = Calendar.current
              let second = calendar.component(.second, from: date)
              return second
          }
      
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              secondesActuelles = récuperLesSecondes(date: Date())
      
              timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(60 - secondesActuelles), repeats: false, block: { (timer) in
                  print("l'heure a changé")
                  self.secondesActuelles = self.récuperLesSecondes(date: Date())
                  print("secondesActuelles : \(self.secondesActuelles)")
      
              })
      }
      

      它工作一次。但在 timeInterval 之后不要改变。

      【讨论】:

        猜你喜欢
        • 2014-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-11
        相关资源
        最近更新 更多