从 iOS 10 中的自定义日期开始取消并重新安排 UserNotification(旧 UILocalNotification)

Cancel and reschedule UserNotification(old UILocalNotification) starting from custom date in iOS 10

我计划每天 UserNorification 在特定时间触发每天,通知用户做某事。但是如果用户在通知被触发前 X 小时这样做,我需要取消今天的通知,在我看来取消所有通知,然后重新安排,但从明天的具体时间开始。 例如,如果今天通知应在 11:00 触发,而用户 "do that thing" 在 10:00,则不应触发 11:00 通知,我需要再次安排在同一时间,但从明天开始。循环继续下去,明天也一样。 我的问题是:

  1. 我是否应该使用以下代码取消安排第一个每日通知:UNUserNotificationCenter.current().removeAllPendingNotificationRequests() ?

  2. 如何安排从特定日期开始的每日通知?

不幸的是,这种调度在 iOS10 中的通知框架变得非常困难。我能找到做类似事情的唯一方法是使用 UNCalendarNotificationTriggerUNTimeIntervalNotificationTrigger并实施UNNotificationContentExtension.

概念如下:

每次执行您的操作时,您都需要重新安排通知。如果时间早于所需的通知时间(例如 11:00 在您的示例中),而不是使用日历触发器重新安排,使用时间间隔触发器为第二天设置一个临时的非重复通知(暂且称它为 tempNotification

let nextDayAt11AMDate = /* the timestamp of tomorrow at 11am */
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: nextDayAt11AMDate.timeIntervalSinceDate(NSDate()), repeats: false)
/* schedule tempNotification */

收到此通知后(假设已实施 UNNotificationContentExtension),在通知到达时调用的扩展视图控制器 didReceive: 方法中,取消现有通知并安排通常使用日历触发器的实际重复通知(我们称之为 actualNoticfication

let date = DateComponents()
date.hour = 11
date.minute = 00 
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
/* schedule actualNotification */

这是一个漫长的变通方法,可能不是很有效,也不是 100% 可靠(例如,如果设备在 tempNotification 到达时关闭,那么 actualNotification 将不会被安排)但是它涵盖了大多数情况。我会很高兴找到比这更好的方法...

经过研究,新的 UserNotifications 框架无法做到这一点。我们必须使用旧的 UILocalNotification 方法来实现这一点。因为该代码在 iOS10 中已弃用,我已将支持的版本更改为 9+,因此不会有警告。这是一种永久性的方法,但希望 Apple 能够在新框架中实现和扩展旧功能。