Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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:

  1. Should I unschedule the first daily notifications using the following code: UNUserNotificationCenter.current().removeAllPendingNotificationRequests() ?

  2. How to schedule daily notifications starting from a specific date?

like image 634
Slavcho Avatar asked Dec 17 '16 19:12

Slavcho


1 Answers

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 UNTimeIntervalNotificationTriggerAND 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...

like image 113
spassas Avatar answered Oct 31 '22 17:10

spassas