2016-11-23 42 views
0

我试图制作一个简单的应用程序,每7分钟触发一次闹钟(可配置当然)该应用程序是否在前台。如何为swift 3中的iPhone制作重复倒计时器应用程序,即使在后台也会每隔'x'分钟发出通知

尽管做一个硬编码的重复定时器很容易,但添加任何类型的前端界面似乎都会对我的策略产生一定的影响,并暗示我可能完全采用了错误的方法。

例如,如果我只有一个开始/停止按钮,暂停现有计时器需要取消后台通知,但要记录剩余的时间。然后,当它恢复时,剩余时间需要重新创建通知。例如,如果它是一个5分钟的计时器,那只剩下2分钟时暂停,当它恢复时,它被设置为一个2分钟的倒数计时器。所以如果我把应用程序放在后台,我会得到一个通知时间已过,但它不会自动开始5分钟的倒计时,而只会回到2分钟。我需要能够创建重复的通知,并且在“剩余”时间过期后切换到整个持续时间。

我可以在通知上创建一个动作,如果用户按下它将重新启动计时器,但为此目的,我需要计时器立即自动重新启动,即使用户忽略它。

我可以很容易地用前台定时器完成这个任务,但是之后我需要强制我的手机永远不会进入睡眠状态,只有当这个应用程序处于前台时才能工作,而手机并不总是这样。

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

我已经对此做了相当多的研究,但似乎无法找到该做什么。如果我可以在触发通知时传递一小段代码来执行代码,那可行,但我认为没有办法做到这一点。

这是我的通知创建的代码看起来像此刻:

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!) 
     } 
    } 
+0

你已经采取了看看苹果公司的本地和远程通知编程指南? https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/index.html –

+0

是的,我无法找到一种方式来执行应用程序在后台时由定时器触发的任意代码。我试图做什么不可能?这对我来说似乎是一个明智的用例。 –

回答

1

五个基本背景,可以在iOS的模式:

  1. 播放音频应用程序可以继续播放和/或在后台录制音频。
  2. 接收位置更新该应用程序可以继续获取回调,因为设备的位置发生变化。
  3. 执行有限长度的任务泛型“无论”的情况下,应用程序可以在有限的时间内运行任意代码。
  4. 流程报亭套件下载 特定于报亭应用程序,该应用程序可以在后台下载内容。
  5. 提供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)

+0

位置策略可能不起作用,因为当我需要重复定时器被触发时,我通常不会移动。检查什么时候只在前台也会使应用程序变得毫无价值,因为我的手机可能会进入睡眠状态,我可能会忘记检查它,然后在事件发生时我将不会收到通知。注册本地通知在计时器第一次到期时工作正常,但那之后的所有时间呢?重复选项不能将定时器重置为原始持续时间。 –

+0

是的,你对位置策略是正确的,所以你必须消除这个选项,我不明白你对本地通知的意思。 iOS默认情况下并没有让你的应用程序在后台运行很长时间,这取决于操作系统,你什么都做不了。所以你的工作必须在前台执行,除了上述状态之外,没有办法在背景中执行你的代码。如果您期待Android中的服务,您的应用程序将毫无用处。您可以使用本地通知注册多个计时器。 – Henawey

+0

此外,您可以更改声音本地通知,您可以创建小部件,这会使您的应用程序无需前台状态工作,但如果小部件本身对用户可见,则小部件将更新数据 – Henawey

相关问题