I have an app that supports multiple windows (iPadOS 13+) and I want to know the proper way to respond to a user tapping on a notification. I want to set up the UI based on the notification that was tapped by the user.
I am setting the UNUserNotificationCenterDelegate
property on the shared instance of UNUserNotificationCenter
like this:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
return true
}
I conform to the UNUserNotificationCenterDelegate
and implement the following method. This method is always triggered when a user interacts with a notification:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// This gets called whenever a notification is tapped, dismissed or a custom action is performed by the user from the system Notification Center UI.
// Should my UI setup code live here?
completionHandler()
}
In the session titled Targeting Content with Multiple Windows, Apple explains that when your app supports multiple windows, the system will use the following property to help determine which window will be presented to the user when they tap on the notification:
// An identifier for the content of the notification used by the system to customize the scene to be activated when tapping on a notification.
response.notification.request.content.targetContentIdentifier
Ultimately UIKit makes no contract as to which scene (window) will be opened in response to the user tapping on a notification, but it will do its best to open the scene (window) that I designate best matches the targetContentIdentifier
for the notification.
If the user taps on a notification while my app is terminated, then when the following function is called on my SceneDelegate
I will be able to access the information about the notification tap inside of the SceneDelegate
:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
connectionOptions.notificationResponse
// Should my UI setup code live here?
// I don't think so because `connectionOptions.notificationResponse` is sometimes nil and this method is only called once when the scene is being connected to a `UISceneSession`
}
This function is not called if my app is not terminated.
It would appear that UNNotificationResponse
has a property called targetScene
and the scene to update should be determined based on this property:
https://developer.apple.com/documentation/usernotifications/unnotificationresponse/3255096-targetscene