1

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?

Peter Ruppert
  • 1,067
  • 9
  • 24
  • Create a `Timer` object, configure its interval and repeatability, and add it to the application's main run loop. You will also want to consider handling events when the app enters and exits the background since the timer will not stop or pause itself. – lurning too koad Oct 28 '20 at 16:10
  • No. It is not possible. If you set `repeats` to `true` the minimum `timeInterval` is 1 minute (60 seconds) – Leo Dabus Oct 28 '20 at 16:30
  • @LeoDabus Sorry, I don't care about 5 seconds that was just an example. My options will all be above 5 minutes so that is fine. I'll edit the question. – Peter Ruppert Oct 28 '20 at 16:46
  • This is not directly solvable. You'll need to build a one-off Calendar trigger, and then create a TimeInterval trigger when it's the right time. See also https://stackoverflow.com/questions/41768342/repeating-local-notification-is-triggered-immediately-how-to-defer?rq=1 – Rob Napier Oct 28 '20 at 17:01

1 Answers1

0

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.

mxlhz
  • 1,033
  • 11
  • 21