swift 3:手表应用:如果手表进入休眠状态,界面控制器之间会有延迟

swift 3: Watch app: if watch goes to sleep there's a delay between interface controllers

我有一个倒计时界面控制器,一旦计时器下降到 00:00,它就会启动另一个界面控制器。如果我在计时器达到 00:00 之前保持手表处于活动状态,那么第二个界面控制器将按预期启动。但是,如果手表进入休眠状态,即使它在计时器到达 00:00 之前处于活动状态,在第二个界面控制器启动之前也会有几秒到一分钟多的延迟。

这个缺陷在手表模拟器运行时没有出现,只是当我在实际设备上运行时

我正在使用 Xcode 8 和 swift 3。

这是我来自第一个界面控制器的代码:

// this func will update the countdown timer
@objc private func updateTimer() {
    totalNumberOfSeconds += 1
    numberOfSeconds += 1
    if (numberOfSeconds == numSecondsInMinute) {
        numberOfSeconds = 0
    }

    // only attempt to open the RacingTimer interface if this IC is visible
    if (isStillVisible) {
        // change to the Racing Timer if the countdown timer hits 00:00
        if (totalNumberOfSeconds > originalSecondsTimeInterval) {
            // the watch must have gone to sleep when the countdown timer
            // hit 00:00, so the total num secs is past the orig timer
            // set the numberOfSeconds to total - original to pass to RacingTimer
            numberOfSeconds = totalNumberOfSeconds - originalSecondsTimeInterval

            // launch the racing timer
            WKInterfaceController.reloadRootControllers(withNames: ["RacingTimer"], contexts: [numberOfSeconds])

            // destroy the timer and reset the vars
            countdownClock.invalidate()
            numberOfSeconds = 0
            totalNumberOfSeconds = 0
        } else if (totalNumberOfSeconds == originalSecondsTimeInterval) {
            // launch the racing timer
            WKInterfaceController.reloadRootControllers(withNames: ["RacingTimer"], contexts: nil)

            // destroy the timer and reset the vars
            countdownClock.invalidate()
            numberOfSeconds = 0
            totalNumberOfSeconds = 0
        }
    }
}


override func awake(withContext context: Any?) {
    super.awake(withContext: context)

    // get race and timer data
    let numSecs = raceDS.timer * 60
    originalSecondsTimeInterval = numSecs
    cdt = NSDate(timeIntervalSinceNow: TimeInterval(numSecs))
    countdownTimer.setDate(cdt as Date)
    countdownClock = Timer.scheduledTimer(timeInterval: 1, target: self,   selector: #selector(updateTimer), userInfo: nil, repeats: true)
    countdownTimer.start()
}


override func willActivate() {
    // This method is called when watch view controller is about to be visible to user
    super.willActivate()
    nearestMinuteButtonOutlet.setTitle("will activate") // debug only
    didAppear()
}


// set the visible boolean to true
override func didAppear() {
    super.didAppear()
    isStillVisible = true
    nearestMinuteButtonOutlet.setTitle("did appear")  // debug only
}


// set the boolean to false
override func didDeactivate() {
    // This method is called when watch view controller is no longer visible
    super.didDeactivate()
    isStillVisible = false
    nearestMinuteButtonOutlet.setTitle("sleeping")  // debug only
}

我真的很困惑为什么手表进入休眠状态会有延迟。任何帮助将不胜感激。 TIA.

watchOS3 开始,没有在后台设置 Timer 运行 的解决方案。 Timer 对象也不应该用于 iOS 上的精确时间测量。在 iOS 上,您可以选择使用 CADisplayLink 来获得准确的计时,但是,这在 watchOS3/4 上不可用。

为了在后台测量时间,您应该在应用程序进入后台之前保存当前日期,并在应用程序再次启动时计算经过的时间。

如果您只需要其他 InterfaceController 在用户打开您的应用程序时可见,您可以使用使用日期描述的方法,您可以导航到您的其他 InterfaceController 作为一旦用户再次打开您的应用程序。

如果您需要在倒计时结束时执行一些代码,您应该安排一个后台任务,它们是目前 watchOS 后台中唯一的 运行 代码方法.