I'm scheduling a daily UserNorification
to trigger everyday at a specific time, notifying the user to do something. But if the user does that X hours before the notification is fired, I need to cancel today's notification, in my opinion cancel all, and reschedule again but from tomorrow's specific time.
For example, if today the notification should fire at 11:00 and the user "do that thing" at 10:00, the 11:00 notification should not be fired, and I need to schedule again at the same time but starting from tomorrow. And the cycle goes on and on, same for tomorrow.
My questions are:
Should I unschedule the first daily notifications using the following code: UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
?
How to schedule daily notifications starting from a specific date?
Unfortunately, this kind of scheduling became ridiculously hard with the notifications framework in iOS 10. The only way I could find to do something similar is to use a hybrid of both UNCalendarNotificationTrigger
and UNTimeIntervalNotificationTrigger
AND implement a UNNotificationContentExtension
.
The concept is the following:
Every time your action is being performed you need to reschedule your notifications. If the time is earlier than the desired notification time (e.g 11:00 in your example), instead of using a calendar trigger to reschedule, use a time interval trigger to set one, temporary, non-repeating notification for the next day (let's call it tempNotification
)
let nextDayAt11AMDate = /* the timestamp of tomorrow at 11am */
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: nextDayAt11AMDate.timeIntervalSinceDate(NSDate()), repeats: false)
/* schedule tempNotification */
When this notification is received (and provided that a UNNotificationContentExtension
has been implemented), in your extension's view controller didReceive:
method which is called when the notification arrives, cancel existing notifications and schedule the actual, repeating notification normally using a calendar trigger (let's call it actualNoticfication
)
let date = DateComponents()
date.hour = 11
date.minute = 00
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
/* schedule actualNotification */
It's a long work-around, probably not very efficient and also not 100% reliable (e.g if the device is closed when the tempNotification
arrives then the actualNotification
will not be scheduled) but it covers the majority of cases. I would be very glad to find a better way than that...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With