swiftxcodeunnotificationrequest

How do I schedule a notification at a specific time, and then repeat it every x amount of time?


I am making a reminder app where you can schedule a reminder, that will then repeat every x seconds/minutes/hours/days etc.

If I want it to repeat every x amount of time I can do it like so:

func addNotification() {

let content = UNMutableNotificationContent()
content.title = "title"
// show this notification 5 minutes from now
var trigger: UNTimeIntervalNotificationTrigger
trigger = UNTimeIntervalNotificationTrigger(timeInterval: 300, repeats: true)
// choose a random identifier
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)

// add our notification request
UNUserNotificationCenter.current().add(request)

}

This is essentially what I want, but instead of starting 5 minutes from now, I want to be able to choose the start date and then have it repeat every 5 minutes seconds from that initial start date.

Is this possible?


Solution

  • From what I know it's not possible to repeat a notification every X seconds (or something else) after a specific date.

    I think the "best" option here is to use UNCalendarNotificationTrigger instead and schedule 60/5 = 12 notification (so 1 every 5 seconds) starting from the given date.

    Something like this:

    // this is your reference date - here it's now + 5 seconds just for this example
    var referenceDate = Calendar.current.date(byAdding: .second, value: 5, to: Date())!
    for i in 0...11 { // one every 5 seconds, so total = 12
        let content = UNMutableNotificationContent()
        content.title = "Notif \(i)"
        content.body = "Body"
    
        var dateComponents = DateComponents(calendar: Calendar.current)
        // 5 seconds interval here but you can set whatever you want, for hours, minutes, etc.
        dateComponents.second = 5
        //dateComponents.hour = X
        // [...]
        
        guard let nextTriggerDate = dateComponents.calendar?.date(byAdding: dateComponents, to: referenceDate),
              let nextTriggerDateCompnents = dateComponents.calendar?.dateComponents([.second], from: nextTriggerDate) else {
            return
        }
        referenceDate = nextTriggerDate
    
        print(nextTriggerDate)
        let trigger = UNCalendarNotificationTrigger(dateMatching: nextTriggerDateCompnents, repeats: true)
        let request = UNNotificationRequest(identifier: "notif-\(i)", content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request)
    }
    

    Now based on that, you would need to handle when a user taps one of the notifications in order to cancel all the others. But that's another topic here and I leave it up to you to find the logic for that.