From a6c63d4f50551eb1dc90a5825ab0b5cca44250f2 Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Fri, 30 Mar 2018 09:25:41 +0100 Subject: [PATCH] [links] Introduce JS initialised method to improve getInitialLink --- ios/RNFirebase/links/RNFirebaseLinks.m | 37 +++++++++++++++++++++----- lib/modules/links/index.js | 6 +++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/ios/RNFirebase/links/RNFirebaseLinks.m b/ios/RNFirebase/links/RNFirebaseLinks.m index 63ce16c8..47d30a8a 100644 --- a/ios/RNFirebase/links/RNFirebaseLinks.m +++ b/ios/RNFirebase/links/RNFirebaseLinks.m @@ -8,8 +8,16 @@ @implementation RNFirebaseLinks static RNFirebaseLinks *theRNFirebaseLinks = nil; +static NSString *initialLink = nil; +static bool jsReady = FALSE; + (nonnull instancetype)instance { + // If an event comes in before the bridge has initialised the native module + // then we create a temporary instance which handles events until the bridge + // and JS side are ready + if (theRNFirebaseLinks == nil) { + theRNFirebaseLinks = [[RNFirebaseLinks alloc] init]; + } return theRNFirebaseLinks; } @@ -39,7 +47,7 @@ RCT_EXPORT_MODULE(); FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; if (dynamicLink && dynamicLink.url) { NSURL* url = dynamicLink.url; - [RNFirebaseUtil sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString]; + [self sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString]; return YES; } return NO; @@ -56,7 +64,7 @@ continueUserActivity:(NSUserActivity *)userActivity NSLog(@"Failed to handle universal link: %@", [error localizedDescription]); } else { NSURL* url = dynamicLink ? dynamicLink.url : userActivity.webpageURL; - [RNFirebaseUtil sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString]; + [self sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString]; } }]; } @@ -67,7 +75,7 @@ continueUserActivity:(NSUserActivity *)userActivity // ******************************************************* - (void)sendLink:(NSString *)link { - [RNFirebaseUtil sendJSEvent:self name:LINKS_LINK_RECEIVED body:link]; + [self sendJSEvent:self name:LINKS_LINK_RECEIVED body:link]; } // ** Start React Module methods ** @@ -127,7 +135,7 @@ RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPr if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) { NSURL* url = (NSURL*)self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]; FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; - resolve(dynamicLink ? dynamicLink.url.absoluteString : nil); + resolve(dynamicLink ? dynamicLink.url.absoluteString : initialLink); } else if (self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey] && [self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey][UIApplicationLaunchOptionsUserActivityTypeKey] isEqualToString:NSUserActivityTypeBrowsingWeb]) { NSDictionary *dictionary = self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]; @@ -144,11 +152,29 @@ RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPr } }]; } else { - resolve(nil); + resolve(initialLink); } } +RCT_EXPORT_METHOD(jsInitialised:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { + jsReady = TRUE; + resolve(nil); +} + // ** Start internals ** + +// Because of the time delay between the app starting and the bridge being initialised +// we catch any events that are received before the JS is ready to receive them +- (void)sendJSEvent:(RCTEventEmitter *)emitter name:(NSString *)name body:(id)body { + if (emitter.bridge && jsReady) { + [RNFirebaseUtil sendJSEvent:emitter name:name body:body]; + } else if (!initialLink) { + initialLink = body; + } else { + NSLog(@"Multiple link events received before the JS links modules has been initialised"); + } +} + - (FIRDynamicLinkComponents *)buildDynamicLink:(NSDictionary *)linkData { @try { NSURL *link = [NSURL URLWithString:linkData[@"link"]]; @@ -285,4 +311,3 @@ RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPr @implementation RNFirebaseLinks @end #endif - diff --git a/lib/modules/links/index.js b/lib/modules/links/index.js index 1a744327..54c47dd1 100644 --- a/lib/modules/links/index.js +++ b/lib/modules/links/index.js @@ -2,6 +2,7 @@ * @flow * Dynamic Links representation wrapper */ +import { Platform } from 'react-native'; import DynamicLink from './DynamicLink'; import { SharedEventEmitter } from '../../utils/events'; import { getLogger } from '../../utils/log'; @@ -36,6 +37,11 @@ export default class Links extends ModuleBase { SharedEventEmitter.emit('onLink', link); } ); + + // Tell the native module that we're ready to receive events + if (Platform.os === 'ios') { + getNativeModule(this).jsInitialised(); + } } /**