Trigger UILocalNotification for every 14 days (fortnightly) Swift

2.2k views Asked by At

The question has been already answered on SO. Here is the reference:

iOS Notification Trigger: fortnightly and/or quarterly

But what I have tried is so far:

var fortnightPart1 = DateComponents()
fortnightPart1.weekday = Calendar.current.component(.day, from: Sdate) //(Day..here Sunday)
fortnightPart1.weekdayOrdinal = 2 //= n == (nth Day in the month...here 2nd Sunday in every month month)
fortnightPart1.hour = Calendar.current.component(.hour, from: Sdate)
fortnightPart1.minute = Calendar.current.component(.minute, from: Sdate)
fortnightPart1.second = Calendar.current.component(.second, from: Sdate)
trigger = UNCalendarNotificationTrigger(dateMatching: fortnightPart1, repeats: repeate)

I can't able to achieve it it after 14 days. Although, it comes on a random data. Can anybody check what's wrong with the code?

Update:

As per your suggestion (https://stackoverflow.com/a/46072497/7408802), here is the final code which worked!

//for 1st time notification
 let center = UNUserNotificationCenter.current()
 let content = UNMutableNotificationContent()
 content.title = title
 content.body = body
 content.categoryIdentifier = "\(id)"
 content.sound = UNNotificationSound.default()
 fortnightPart1.hour = Calendar.current.component(.hour, from: dateToFireON)
 fortnightPart1.minute = Calendar.current.component(.minute, from: dateToFireON)
 fortnightPart1.second = Calendar.current.component(.second, from: dateToFireON)
 trigger = UNCalendarNotificationTrigger(dateMatching: fortnightPart1, repeats: false)
 content.userInfo = ["NotificationID": id,"repeate":repeate,"resedule":true]
 let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
 center.add(request)

//when first notification triggered, we need to set another for 14 days repeat in UIApplicationDelegate
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
    let center = UNUserNotificationCenter.current()
    let content = UNMutableNotificationContent()
    content.title = notification.alertTitle!
    content.body = notification.alertBody!
    content.categoryIdentifier = "\(reminderId)"
    content.userInfo = ["NotificationID": reminderId,"repeate":true,"resedule":false]
    content.sound = UNNotificationSound.default()
    let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 1209600, repeats: true)
    let request = UNNotificationRequest(identifier:"\(reminderId)", content: content, trigger: trigger)
    center.add(request, withCompletionHandler: nil)
}
2

There are 2 answers

4
Dávid Pásztor On BEST ANSWER

What you want to achieve is not possible using simple UNNotificationTriggers. For a notification to be repeated biweekly, you would need to set up a UNTimeIntervalNotificationTrigger with a timeInterval equivalent to two weeks. However, you cannot specify the first fire date of a time interval trigger, it start "ticking" as soon as you schedule it.

On the other hand, UNCalendarNotificationTrigger can be scheduled to fire at a certain date, but the problem with this is that you cannot specify a custom repeat interval for the notification trigger.

What you would need is to first, set up a non-repeating UNCalendarNotificationTrigger for the date specified by the user and once that notification is delivered, set up a UNTimeIntervalNotificationTrigger that fires every two weeks. The only issue with this approach is that the user would see a notification at the specified date as well, not only every two weeks after that. However, you can circumvent this issue by setting the notification to be delivered two weeks after the specified date, then the user won't notice the difference between the notifications.

1
Amrit Trivedi On

@David answer is pretty much right. I want to add one thing here. If user will not tap on notification then you can not schedule other notifications. You can use background fetch for that. If IOS trigger background fetch then check current date with your schedule dates and generate new notifications.