如何在 swift 3 中为 iPhone 制作重复倒数计时器应用程序,即使在后台,它也每 'x' 分钟触发一次通知



我正在尝试制作一个简单的应用程序,该应用程序每7分钟(当然可以配置)发出警报,无论该应用程序是否在前景中。

尽管只能制作一个硬编码的重复计时器来实现此目的,这很容易,添加任何类型的前端界面似乎都会为我的策略带来一把扳手,这向我表明我可能完全采用了错误的方法。

例如,如果我只有一个开始/停止按钮,则暂停现有计时器需要取消背景通知,但要跟踪剩余的时间。然后,恢复它时,需要在剩余时间内重新创建通知。例如,如果它是一个5分钟的计时器,则仅剩2分钟的时间就暂停了,当它恢复时,它将设置为2分钟的倒计时计时器。因此,如果我将该应用程序放在后台,我会收到一条通知,说时间已经过去了,但是它不会自动启动5分钟的倒计时,而是返回2分钟。我需要能够创建重复的通知,但一旦"剩余"时间到期,我需要切换到完整的持续时间。

我可以对通知创建一个操作,如果用户按下将重新启动计时器,但是为此,我需要计时器即使用户忽略了计时器,也需要立即自动重新启动。

我可以轻松地使用前景计时器来实现这一目标,但是然后我需要强迫手机永远不会入睡,并且只有在此应用程序在前景中,这只能在手机上进行。

其他计时器应用程序可以弹出背景通知正好可以。日历应用程序可以安排任意时间的背景通知。我怀疑日历应用程序计划的所有未来(包括重复)发起的那一刻,因为即使手机已重新启动,并且日历应用程序也从未启动。因此,日历应用程序通知机制必须足够聪明才能发出警报,然后安排下一个警报,这正是我在这里需要的那种机制。我认为也许日历应用程序仅使用基于服务器的远程通知,并且服务器处理了所需的更复杂的逻辑,但是这是不正确的,因为即使没有任何Internet连接,日历应用程序也可以正常工作。

我已经对此做了很多研究,但似乎找不到该怎么做。如果我可以通过触发通知时执行的一小部分代码,那将有效,但是我看不到这样做。

这是我的通知创建代码目前的样子:

    let content = UNMutableNotificationContent()
    content.title = "Context switch"
    content.body = "(Int(initialDuration / 60)) minutes have passed."
    content.sound = UNNotificationSound.default()
    content.categoryIdentifier = generalCatId
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: remaining, repeats: true)
    let request = UNNotificationRequest(identifier: requestIdentifier, content: content, trigger: trigger)
    let center = UNUserNotificationCenter.current()
    center.delegate = self
    center.add(request) { (error) in
        if error != nil {
            print(error!)
        }
    }

iOS中可用的五个基本背景模式:

  1. 播放音频该应用程序可以在后台继续播放和/或录制音频。
  2. 接收位置更新随着设备的位置更改,该应用程序可以继续接听回调。
  3. 执行有限长度任务通用的" whyther"情况,该应用程序可以在有限的时间内运行任意代码。
  4. Process报摊套件下载该应用程序特定于报摊应用程序,可以在后台下载内容。
  5. 提供Veage-Over-IP(VoIP)服务该应用程序可以在后台运行任何任意代码。当然,苹果会限制其使用,以便您的应用也必须提供VoIP服务。

ref

对不起,您可以永远在后台运行计时器,因此您必须考虑做某事并不取决于执行有限长度任务背景模式。

所以您有3个选项:

  1. 注册您的应用程序以接收位置更新,此需要请求使用位置服务requestAlwaysAuthorization()

  2. 每次进入前景时检查设备的时间,如果用户手动更改时间,这将无法正常工作,所以最好的事情就是调用Web服务以获取UTC的当前时间

    http://www.timeapi.org/utc/now

  3. 当您的应用发送到后台

    时,请注册到本地通知
        var localNotification = UILocalNotification()
        localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
        localNotification.alertBody = "Time out"
        localNotification.timeZone = NSTimeZone.defaultTimeZone()
        localNotification.applicationIconBadgeNumber = UIApplication.sharedApplication().applicationIconBadgeNumber + 1
    

然后安排此通知UIApplication.sharedApplication().scheduleLocalNotification(localNotification)

最新更新