swift 3:手表应用:如果手表进入睡眠状态,界面控制器之间会有延迟
Posted
技术标签:
【中文标题】swift 3:手表应用:如果手表进入睡眠状态,界面控制器之间会有延迟【英文标题】:swift 3: Watch app: if watch goes to sleep there's a delay between interface controllers 【发布时间】:2017-08-03 19:08:25 【问题描述】:我有一个倒数计时器接口控制器,一旦计时器下降到 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。
【问题讨论】:
好的,所以我找到了问题所在。不是第二个接口控制器延迟启动,而是当手表进入睡眠状态时,Timer 变量(countdownClock)不会在后台继续处理。它停止。发生这种情况时,不会调用 updateTimer() 函数,因此不会增加 totalNumberOfSeconds 变量等。 手表进入休眠状态时,有没有办法让倒计时时钟在后台运行? 【参考方案1】:截至watchOS3
,没有解决方案让Timer
在后台运行。 Timer
对象也不应用于ios
上的精确时间测量。在iOS
上,您可以选择使用CADisplayLink
来获得准确的计时,但是,这在watchOS3/4
上不可用。
为了在后台测量时间,您应该在应用程序进入后台之前保存当前日期,并计算再次启动应用程序时所经过的时间。
如果您只需要在用户打开您的应用程序时看到另一个InterfaceController
,您可以使用使用日期描述的方法,并且您可以在用户打开您的应用程序后立即导航到您的另一个InterfaceController
再次应用。
如果你需要在倒计时结束时执行一些代码,你应该安排一个后台任务,它们是目前在watchOS
后台运行代码的唯一方法。
【讨论】:
谢谢大卫。我在其他板上发现了类似的问题并建议了解决方法,所以这就是我要采取的方向。我只需将日期/时间戳保存在 didDeactivate() 中,然后计算 willAppear() 启动后经过的时间,并将经过的时间添加到我的总秒数计数器中。有点难看,但如果这是我需要的,那我就需要这样做。以上是关于swift 3:手表应用:如果手表进入睡眠状态,界面控制器之间会有延迟的主要内容,如果未能解决你的问题,请参考以下文章