【问题标题】:Countdown timer, that continue running in background倒数计时器,在后台继续运行
【发布时间】:2017-03-16 13:17:37
【问题描述】:

我需要创建计时器,它将继续在后台状态下运行,并在应用程序进入前台状态后更新 UI。 最恰当的例子是 QuizClash 应用程序:

我有以下两个想法:

  1. beginbackgroundTaskWithExpirationHandler

    • 创建第一个计时器(30 秒间隔,不可重复)
    • 创建第二个计时器(0.01 秒间隔,可重复)
    • 第一个计时器将触发 [self timeExiped] 方法,该方法将显示一些 UI 更新
    • 第二个计时器将触发上图中 ProgressBar 的更新
    • 将其全部包装在 beginbackgroundTaskWithExpirationHandler 方法中

    疑问:如果主计时器在后台状态下过期,UI 更新将不会显示(?)

  2. 状态恢复

    • 启动相同的计时器
    • 使用 encode​Restorable​State​With​Coder:​​以保存当前时间戳,当进入后台时
    • 使用 decode​Restorable​State​With​Coder:​​获取保存的时间戳和现在之间的差异。
    • 主定时器无效
    • 使用 (remains_seconds - time_difference_seconds) 启动新的主计时器

    疑问:这是否是一个可行的选择,因为我没有经验,暂时无法尝试?

如果您有任何其他想法,或者可以在上述 2 中指出我,我会放啤酒,如果您曾经在莫斯科 :)

【问题讨论】:

  • 当您的应用处于后台时,您无法进行 UI 操作。如果我没记错的话,后台任务对您不起作用,因为它有大约 30 秒的时间限制。对于这项任务,状态恢复似乎过于复杂。您为什么不保留应用程序进入后台的时间,并计算当应用程序再次进入前台时您的应用程序在后台花费了多长时间。您可以简单地将timeWhenAppGoesBackground 写入NSUserDefaults
  • 我不需要在后台更新 UI,因为它没有意义。但是是的,NSUserDefaults 可以作为存储时间戳的一个选项,谢谢。

标签: ios objective-c timer


【解决方案1】:

计时器的用途是什么?

如果要触发 UI 更改,尝试让它“在后台运行”是没有意义的,因为没有要更新的 UI。

使用任何方法,您几乎肯定会想要使用时间戳...当应用程序返回前台时,获取自上次时间戳以来经过的时间,根据需要更新您的 UI,并为前台活动重新启动 Timer /更新。

【讨论】:

  • 主计时器(约 30 秒)的目的是: 1. 使第二个计时器无效,它会更新 ProgressBar 2. 在触发时执行一些 UI 操作。第二个计时器(约 0.01 秒)的目的只是为了更新 ProgressBar。但我明白你的意思。我会尝试使用时间戳。
【解决方案2】:

UIApplicationDidBecomeActive 的观察者添加到包含 viewWillAppear 中 ProgressBar 的 ViewController:

NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationDidBecomeActive, object: nil, queue: nil, using: self.applicationBecameActive)

将它放在 viewWillAppear 中,因为 applicationBecameActive 函数应该只在应用程序再次激活时包含进度条的视图控制器位于堆栈顶部时触发。

然后在applicationBecameActive方法中,判断ProgressBar当前的progress值应该是多少,进行相应的更新,重启ProgressBar的progressing。

func applicationBecameActive(notification: Notification){

    //determine where the ProgressBar should be

    //set the ProgressBar progress value

    //restart the ProgressBar progress value updating

}

不要忘记移除 viewWillDissappear 上的观察者:

NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)

【讨论】:

  • 认为它不是 Objective-c,我会考虑使用应用程序生命周期和通知。谢谢!
猜你喜欢
  • 2019-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多