【问题标题】:Keeping timers running when app enters background当应用程序进入后台时保持计时器运行
【发布时间】:2015-08-07 23:00:17
【问题描述】:

我正在制作一个应用程序,该应用程序依赖于每分钟触发一次的计时器,将标签从“还剩 x 分钟”更改为“还剩 (x-1) 分钟。基本上,它每分钟都会减少数字。我需要计时器即使在我关闭应用程序时也能正常工作(不是完全关闭,只需按下主屏幕并让它在后台运行),这样当用户在后台离开应用程序 5 分钟后返回应用程序时,标签会显示“还剩 (x-5) 分钟”。

现在,当我在模拟器中运行它时,它可以完美运行,但是当我在手机上运行它时,它就无法运行。如果我在手机上打开了该应用程序,它可以工作,但如果该应用程序在后台运行,则标签永远不会减少。这可能是由于模拟器和实际 iPhone 处理多任务的方式不同吗?如果是这样,我该如何更改我的代码,以便计时器仍会每分钟更新一次标签,以便在用户重新打开应用程序时显示正确的数字?

这是我的计时器设置:

var individualTaskTimer = NSTimer()

func createTimerForTopTask(){
    individualTaskTimer = NSTimer.scheduledTimerWithTimeInterval(tasks[0].minutes * 60, target: self, selector: "deleteTopTask", userInfo: nil, repeats: true)
}

【问题讨论】:

  • 这不一定是一个解决方案,但 Ole Begemann 写了一篇关于闹钟应用程序如何在 iOS 上处理多任务处理的高级文章。 oleb.net/blog/2014/02/alarm-clock-apps-ios
  • 8.0 和 11.0 Beta 2 之间的 iOS Simualtor 运行时无法在应用程序进入后台时暂停它们。 iOS 11.0 Beta 3 Simulator(它是 Xcode 9.0 Beta 3 的一部分)解决了这个问题。应适当暂停后台应用以更好地匹配设备行为。

标签: ios swift


【解决方案1】:

正如 Ewan Mellor 的回答中提到的,当应用程序处于后台时,您将无法依赖计时器。因此,当您的应用返回前台时,您需要根据需要进行调整。

在第一次阅读文档时,似乎viewWillAppearviewWillDisappear(或viewDidDisappear)是处理此问题的正确位置。但是,当应用移入/移出后台时,它们不会被调用。

相反,您可以使用两个通知,UIApplicationWillResignActiveNotificationUIApplicationDidBecomeActiveNotification。当它即将进入后台时,第一个通知将发送到您的应用程序。第二个通知将在您的应用即将返回前台时发送到您的应用。

所以在viewWillAppear你可以按如下方式注册通知:

override func viewWillAppear(animated: Bool) {
   // some other code 
   NSNotificationCenter.defaultCenter().addObserver(self, selector: "activeAgain", name: "UIApplicationDidBecomeActiveNotification", object: nil)
   NSNotificationCenter.defaultCenter().addObserver(self, selector: "goingAway", name: "UIApplicationWillResignActiveNotification", object: nil)

}

其中activeAgaingoingAway 是您编写的用于启用和禁用计时器的两个函数。因此,根据您问题中的代码 sn-p,它们看起来像这样:

func activeAgain() {
  let newTime = // calculate how much time is left (in seconds)
  individualTaskTimer = NSTimer.scheduledTimerWithTimeInterval(newTime, target: self, selector: "deleteTopTask", userInfo: nil, repeats: true)

}

func goingAway() {
  individualTaskTimer.invalidate()
}

请注意,当您离开此视图时,您需要取消注册通知。在viewWillDisappear 中执行此操作可能是一个好地方。

【讨论】:

    【解决方案2】:

    你不能这样做。当你的应用程序进入后台时,iOS 会在一段时间后暂停你的应用程序。只需在应用返回前台时使用正确的时间更新您的标签。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-18
      • 1970-01-01
      • 1970-01-01
      • 2014-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多