iOS 10.2 UNUserNotificationCenterDelegate / UNTimeIntervalNotificationTrigger Bug?

521 Views Asked by At

I'm experiencing a weird bug with iOS 10.2 with UNTimeIntervalNotificationTrigger and UNUserNotificationCenterDelegate. Basically the notification I create is getting picked up by the delegate instantly and then again at the correct internal. This only happens when the repeats property is set to true on the trigger.

Has anyone else seen this issue? Right now I'm thinking I need to check the trigger date in the delegate and compare to a stored registered date — but I want to avoid that if possible.

Sample code to create notification

let content = UNMutableNotificationContent()
content.body = "My notification message"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true)
let request = UNNotificationRequest(identifier: "MY_IDENTIFIER", content: content, trigger: trigger)

UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)

UNUserNotificationCenterDelegate is fired directly after .add

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
      // Code called here instantly when trigger repeats = true
      // Code called again at proper interval as well (60 seconds)
}

If I change the trigger to repeats false, this doesn't happen

  let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: false)
1

There are 1 best solutions below

0
rosem On

I still haven't found the root problem or have seen/heard anyone else with the issue. In the mean time this was my fix (although I wish it just worked correctly).

I created a dictionary to store the time the notification was fired. I use the notification identifier as the key:

scheduledTimes[identifier] = CACurrentMediaTime()
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)

Then in the delegate, I can compare it to the current time to see if I should ignore it or not:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    let identifier = notification.request.identifier

    // Required for 10.2?
    // Adding a notification request to the notification center immediately fires this delegate when the trigger is set to repeat
    if let scheduledTime = scheduledTimes[identifier] {
        if CACurrentMediaTime() - scheduledTime < 1.0 {
            completionHandler([])
            return
        }
    }

    // Parse the notification into an internal notification and show it

    completionHandler([])
}

The time between adding and the delegate call is very short, something like 0.04 on average.