iosswiftapple-push-notificationswatchoswatchos-3

Handling push notifications while watchOS app is in the foreground?


I am building iOS + watchOS apps that need to notify users with updated information across all of the possible combinations of iOS and watch app states: when both the iOS and watchOS are running in the foreground, when they're both running in the background, and when one or the other is in the background.

I am successfully handling push notifications for three of these four situations. Where I'm stuck is when the watch app is open in the foreground but the iOS app is in the background- I can't find any method for the watch Notification Controller, its ExtensionDelegate, or for the iOS AppDelegate that will fire when a remote notification is pushed in this situation.

In iOS AppDelegate, this fires when a notification is pushed while iOS app is in foreground and watch app is in either state:

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification,
                            withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)

In WatchKit Extension NotificationController, this fires when a notification is pushed while both iOS and watch app are in the background:

override func didReceive(_ notification: UNNotification, withCompletion completionHandler: @escaping (WKUserNotificationInterfaceType) -> Swift.Void) { ... }

Yet if the watch app is in the foreground and the iOS app is in the background when a notification is pushed, the notification banner appears on the iPhone (even when the screen is locked), and I have found no way to handle it and update the watch unless the watch is also in the background at that moment.

Any ideas?


Solution

  • Figured this out. To handle notifications when the watch app is either in background and foreground, it seems like you have to implement methods in both the didReceive method in the NotificationController (for notifications while in background) and the UNUserNotificationDelegate protocol in the ExtensionDelegate with the willPresent method (for notifications while in foreground):

    func userNotificationCenter(_: UNUserNotificationCenter, willPresent: UNNotification, withCompletionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("willPresent fired from watch delegate")
    }
    

    What had confused me was that the docs say:

    The User Notifications framework offers a unified API for use in iOS, watchOS, and tvOS apps, and supports most tasks associated with local and remote notifications. Here are some examples of tasks you can perform with this framework...

    But while they go through this for iOS, tvOS, and macOS, the docs don't specify exactly how do this for the watch.

    Going through the registration and device token steps is not necessary in the Watch ExtensionDelegate (and actually impossible because you need the UIApplication module to do it), but it is necessary to invoke:

    UNUserNotificationCenter.current().delegate = self
    

    upon launching the ExtensionDelegate.