Remotely dismissing notifications on iOS

I am sending push notifications on iOS, and I can receive and display them correctly. I want to be able to dismiss notifications that have been read server-side (e.g. on a different device) so I am trying to send a custom notification payload alongside a badge counter update, that specifies what notification IDs to remove. I then use removeDeliveredNotifications on the IDs I get. However, it doesn't seem to be working. I am setting the identifier using the apns-collapse-id header and I do see that reflected on the device side. Any ideas what I might be doing wrong?

This is how I'm handling push notifications:

  func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    willPresent notification: UNNotification,
    withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
  ) {
    let customPayload = notification.request.content.userInfo
    if let dismissedNotifications = customPayload["dismissed_notifications"] as? [String] {
      center.removeDeliveredNotifications(withIdentifiers: dismissedNotifications)
    }

    completionHandler([.banner, .sound, .badge])
  }

I also tried doing the same thing inside

func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
  )

Thank you!

The issue which doesn't seem to be working is not clear from your question.

Is it that willPresent is not being called? Or that removeDeliveredNotifications is not removing the notifications.

Is your app in the foreground during this? willPresent will only be called when the app is in the foreground.

didReceive response on the other hand is not a function that will be called automatically, but only in response to a user selecting one of the action buttons in the notification.

If you are trying to run this code when the app is not in the foreground, I suggest looking into using a Notification Service Extension as discussed at https://developer.apple.com/documentation/usernotifications/unnotificationserviceextension.

The Notification Service Extension will be executed for every visible push notification. So, it could serve your needs, as long as the user has not disabled the visibility of your notifications through various settings. The service extension will not be executed for push notifications that will not be presented visually.


Argun Tekant /  DTS Engineer / Core Technologies

Ahhh, that's quite helpful! I should mention that I'm very new to iOS development. The willPresent is being called but as you mentioned, only in the foreground. I have additional print statements in my actual code that show that the function is called and that the notification with the correct identifier was received, and I am then calling removeDeliveredNotifications but the notification remains. I basically already had these two functions in my code for handling existing notifications so I put it in there but perhaps I was wrong to do so. I am sending a push notification that updates the badge count, and includes the custom payload to specify which notifications to dismiss. But if no notification is actually displayed as a result of this push, would it not allow me to remove the notification?

I will have to check out the notification service extension later!

If you are calling removeDeliveredNotifications, things should work. But you need to be careful about that call being asynchronous. It will return immediately, but the removal of the notifications will be done in the background and may take some time.

Make sure you understand how asynchronous functions behave and you are not dropping out of scope immediately after the function returns.


Argun Tekant /  DTS Engineer / Core Technologies

Remotely dismissing notifications on iOS
 
 
Q