我正在创建一个简单的应用程序,其中包含记录事件的Today Widget扩展。
用户可以点击应用程序中的按钮或相关的今日小组件来记录事件。只要按下按钮,这些事件就会随Core Data一起保存。
每当在应用程序中记录新事件时,我都会运行一个名为updateLocalNotificationsFromCoreData()
的函数。在清除相应的现有通知后,它会根据Core Data中的最新事件处理UILocalNotifications的设置。
但是,当从Today Widget记录新事件时,我无法使用此功能,因为我需要使用UIApplication.sharedApplication().scheduleLocalNotification()
注册本地通知,而今日Widget扩展中不提供UIApplication
我意识到我可能需要做一些非常规或黑客的工作,所以我试图评估可能的方法,并提出一个相对强大的解决方案。
基本上,我想找到一种可以称呼我的方式
只要记录新事件,updateLocalNotificationsFromCoreData()
就会立即生效。
如果每次记录事件时都无法执行此操作,则另一种方法是定期(稍微频繁地)以另一种方式触发updateLocalNotificationsFromCoreData()
功能。以下是我正在考虑使用的一些解决方案,但我不喜欢其中任何一个:
我正在考虑的一种方法是在某个地方的AppDelegate中运行我的updateLocalNotificationsFromCoreData()
函数,例如didFinishLaunchingWithOptions
。
缺点是需要用户定期打开应用程序。如果用户没有打开它,通知行为就会不一致。我更喜欢一种解决方案,用户只需与今日小部件进行交互,即可在不打开应用程序的情况下可靠地获取本地通知。
我已考虑过将Core Data中的数据同步到服务器,然后根据该功能将推送通知设置到用户手机。
我不喜欢这样,因为我希望用户仍能够在没有互联网连接的情况下收到通知。它还引入了许多与服务器同步数据的额外开销。
当有人使用窗口小部件记录事件时,我可以ping服务器。该服务器可以发回静默内容可用的推送通知,以触发应用在后台运行updateLocalNotificationsFromCoreData()
。
我发现了一个类似的问题(Scheduling local notification from within a Today extension),其中一个答案提出了类似的解决方案。与以前的解决方案不同,接收通知不需要Internet连接,但需要Internet连接以确保在记录新事件时通知是最新的。
我考虑过使用Background Fetch从服务器获取任意内容,然后运行updateLocalNotificationsFromCoreData()
。这将是一种在后台触发更新的方法,尽管如果数据未被使用,获取数据似乎很愚蠢,而且似乎可以拒绝应用程序。如果用户没有大量打开应用程序并且大部分使用今日小部件,系统似乎还存在系统不定期调用后台更新的风险。
这似乎是最愚蠢的方法,但我想我还是会提到它,因为我想到了它。我可以使用其中一种低精度背景位置更新模式来触发updateLocalNotificationsFromCoreData()
。
这将要求用户允许在后台进行定位,这很难解释。并且,它将要求用户至少移动几个块以触发该功能,这可能提供不一致的用户体验。此外,它会因为一个愚蠢的原因而增加应用程序的功耗。
我非常感谢有关如何在没有互联网连接的设备上更改核心数据时可靠地安排本地通知的新想法!
或者,如果这似乎不可能,我会对哪种方法最有意义的反馈表示赞赏。
编辑:我想出了一个新的解决方案。它并不理想,但我认为它比我考虑的其他方法更好。当有人点击按钮记录事件时,我会启动完整的应用程序。这很烦人,因为我拥有了我需要的所有数据,以便在不启动应用程序的情况下向Today提供反馈并在Today Widget中记录事件,但是通过启动应用程序,我有机会检查并安排本地通知
此外,在iOS 9中,对用户的烦恼略微最小化,因为系统范围内"返回"按钮将出现,让我们的应用程序从Today Widget启动后,用户可以轻松返回上一个应用程序。
将来我可以尝试一种解决方案,当互联网连接可用时,使用上述基于服务器的方法之一,然后我会回到这个仅在网络连接不可用时打开应用程序的系统我需要在应用程序中安排本地通知。