11#import " AppDelegate.h"
22#import " RNNCustomViewController.h"
33#import < ReactNativeNavigation/ReactNativeNavigation.h>
4- #import < React/RCTBridge.h>
5- #import < React/RCTLinkingManager.h>
6- #import < React/RCTRootView.h>
74#import < UserNotifications/UserNotifications.h>
85
9- // URLs that arrive (notification tap, openURL) before the JS bridge is
10- // ready are queued here and flushed when the bridge finishes loading.
11- // Without this, cold-start notifications would post `RCTOpenURLNotification`
12- // into the void because RCTLinkingManager hasn't subscribed yet.
13- static NSMutableArray <NSURL *> *gPendingDeepLinkURLs = nil ;
14- static BOOL gJavaScriptDidLoad = NO ;
15-
166#if !RNN_RN_VERSION_79_OR_NEWER
177@interface AppDelegate () <RCTBridgeDelegate, UNUserNotificationCenterDelegate >
188@end
@@ -63,74 +53,16 @@ - (BOOL)application:(UIApplication *)application
6353 return [[RNNCustomViewController alloc ] initWithProps: props];
6454 }];
6555
66- // Receive notification taps (Detox sendUserNotification & real push taps)
56+ // Demo: route notification taps through RNN's deep-linking pipeline by
57+ // installing this AppDelegate as the UNUserNotificationCenter delegate.
58+ // (Apps that already own this delegate via Firebase/OneSignal/etc. can
59+ // instead call `[self dispatchDeepLinkURL:url]` from their existing
60+ // handler — same effect.)
6761 [UNUserNotificationCenter currentNotificationCenter ].delegate = self;
6862
69- // Flush deep links that arrived before the JS bridge was up.
70- // In legacy mode `RCTJavaScriptDidLoadNotification` fires after the
71- // bridge loads JS. In bridgeless/new-arch that notification does NOT
72- // fire, so we also listen for `RCTContentDidAppearNotification` which
73- // is posted by Fabric's root view once content has rendered — by which
74- // point RCTLinkingManager is already instantiated and listening.
75- [[NSNotificationCenter defaultCenter ] addObserver: self
76- selector: @selector (handleJavaScriptDidLoad: )
77- name: RCTJavaScriptDidLoadNotification
78- object: nil ];
79- [[NSNotificationCenter defaultCenter ] addObserver: self
80- selector: @selector (handleJavaScriptDidLoad: )
81- name: RCTContentDidAppearNotification
82- object: nil ];
83-
8463 return YES ;
8564}
8665
87- #pragma mark - Deep linking
88-
89- // Forward foreground URL openings (custom schemes & universal links)
90- // to React Native's Linking module so JS can handle them.
91- - (BOOL )application : (UIApplication *)application
92- openURL : (NSURL *)url
93- options : (NSDictionary <UIApplicationOpenURLOptionsKey, id> *)options {
94- [self dispatchDeepLinkURL: url];
95- return YES ;
96- }
97-
98- // Dispatch a deep link URL. If RCTLinkingManager hasn't subscribed yet
99- // (cold-start, JS bridge still loading), queue it for replay after
100- // RCTJavaScriptDidLoadNotification fires.
101- - (void )dispatchDeepLinkURL : (NSURL *)url {
102- if (url == nil ) { return ; }
103- if (gJavaScriptDidLoad ) {
104- [RCTLinkingManager application: [UIApplication sharedApplication ]
105- openURL: url
106- options: @{}];
107- return ;
108- }
109- if (gPendingDeepLinkURLs == nil ) {
110- gPendingDeepLinkURLs = [NSMutableArray array ];
111- }
112- [gPendingDeepLinkURLs addObject: url];
113- }
114-
115- - (void )handleJavaScriptDidLoad : (NSNotification *)notification {
116- gJavaScriptDidLoad = YES ;
117- NSArray <NSURL *> *pending = [gPendingDeepLinkURLs copy ];
118- [gPendingDeepLinkURLs removeAllObjects ];
119- for (NSURL *url in pending) {
120- [RCTLinkingManager application: [UIApplication sharedApplication ]
121- openURL: url
122- options: @{}];
123- }
124- }
125-
126- - (BOOL )application : (UIApplication *)application
127- continueUserActivity : (NSUserActivity *)userActivity
128- restorationHandler : (void (^)(NSArray <id<UIUserActivityRestoring>> *))restorationHandler {
129- return [RCTLinkingManager application: application
130- continueUserActivity: userActivity
131- restorationHandler: restorationHandler];
132- }
133-
13466#pragma mark - UNUserNotificationCenterDelegate
13567
13668// Surface notifications while the app is in the foreground so the user
@@ -150,9 +82,9 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center
15082 UNNotificationPresentationOptionSound );
15183}
15284
153- // Notification tap → if payload carries `url`, route it through the
154- // existing Linking pipeline so deep linking reacts the same way regardless
155- // of whether the URL came from the OS or a notification .
85+ // Notification tap → if payload carries `url`, route it through RNN's
86+ // deep- linking pipeline (inherited `dispatchDeepLinkURL:` queues until
87+ // the React runtime is ready, then forwards to RCTLinkingManager) .
15688- (void )userNotificationCenter : (UNUserNotificationCenter *)center
15789didReceiveNotificationResponse : (UNNotificationResponse *)response
15890 withCompletionHandler : (void (^)(void ))completionHandler {
@@ -183,4 +115,3 @@ - (NSURL *)bundleURL
183115#endif
184116
185117@end
186-
0 commit comments