diff --git a/FirebaseMessaging/CHANGELOG.md b/FirebaseMessaging/CHANGELOG.md index 9f2346bc2d3..43b71e37230 100644 --- a/FirebaseMessaging/CHANGELOG.md +++ b/FirebaseMessaging/CHANGELOG.md @@ -1,3 +1,7 @@ +# Unreleased +- [fixed] Fixed an issue where deep links were not correctly routed in apps utilizing scene + delegates. (#15987) + # 12.8.0 - [fixed] Fix missing database crash on launch. (#14880) diff --git a/FirebaseMessaging/Sources/FIRMessaging.m b/FirebaseMessaging/Sources/FIRMessaging.m index f8a696516a2..8d6ead5561c 100644 --- a/FirebaseMessaging/Sources/FIRMessaging.m +++ b/FirebaseMessaging/Sources/FIRMessaging.m @@ -390,20 +390,35 @@ - (void)handleIncomingLinkIfNeededFromMessage:(NSDictionary *)message { if (!application) { return; } - id appDelegate = application.delegate; - SEL continueUserActivitySelector = - @selector(application:continueUserActivity:restorationHandler:); + // Use string literal to ensure compatibility with Xcode 26 and iOS 18 + NSString *browsingWebType = @"NSUserActivityTypeBrowsingWeb"; + NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:browsingWebType]; + userActivity.webpageURL = url; + + // first look for a connected scene that can handle the activity + for (UIScene *scene in application.connectedScenes) { + if (scene.activationState == UISceneActivationStateForegroundActive || + scene.activationState == UISceneActivationStateForegroundInactive) { + if ([scene.delegate respondsToSelector:@selector(scene:continueUserActivity:)]) { + id sceneDelegate = (id)scene.delegate; + [sceneDelegate scene:scene continueUserActivity:userActivity]; + return; + } + } + } + + // fallback to the app delegate when a matching scene delegate wasn't found // Due to FIRAAppDelegateProxy swizzling, this selector will most likely get chosen, whether or // not the actual application has implemented // |application:continueUserActivity:restorationHandler:|. A warning will be displayed to the user // if they haven't implemented it. + id appDelegate = application.delegate; + SEL continueUserActivitySelector = + @selector(application:continueUserActivity:restorationHandler:); + if ([NSUserActivity class] != nil && [appDelegate respondsToSelector:continueUserActivitySelector]) { - // Use string literal to ensure compatibility with Xcode 26 and iOS 18 - NSString *browsingWebType = @"NSUserActivityTypeBrowsingWeb"; - NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:browsingWebType]; - userActivity.webpageURL = url; [appDelegate application:application continueUserActivity:userActivity restorationHandler:^(NSArray *_Nullable restorableObjects){