From e2c85b4f7dde75b3370cb7119a2317dc8f12220a Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Tue, 2 Apr 2024 16:03:15 +0800 Subject: [PATCH] [iOS] Support launchOptions in bridgeless mode --- .../Libraries/AppDelegate/RCTRootViewFactory.mm | 7 ++++--- .../Libraries/LinkingIOS/RCTLinkingManager.mm | 12 ++++++++---- packages/react-native/React/Base/RCTBridgeProxy.h | 3 ++- packages/react-native/React/Base/RCTBridgeProxy.mm | 6 ++++-- .../react/runtime/platform/ios/ReactCommon/RCTHost.h | 3 ++- .../runtime/platform/ios/ReactCommon/RCTHost.mm | 10 ++++++++-- .../runtime/platform/ios/ReactCommon/RCTInstance.h | 3 ++- .../runtime/platform/ios/ReactCommon/RCTInstance.mm | 6 +++++- 8 files changed, 35 insertions(+), 15 deletions(-) diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm index cede47e1761d91..168987c81c625c 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm @@ -123,7 +123,7 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName RCTEnableTurboModuleInterop(YES); RCTEnableTurboModuleInteropBridgeProxy(YES); - [self createReactHostIfNeeded]; + [self createReactHostIfNeeded:launchOptions]; RCTFabricSurface *surface = [_reactHost createSurfaceWithModuleName:moduleName initialProperties:initProps]; @@ -207,7 +207,7 @@ - (void)createBridgeAdapterIfNeeded #pragma mark - New Arch Utilities -- (void)createReactHostIfNeeded +- (void)createReactHostIfNeeded:(NSDictionary *)launchOptions { if (_reactHost) { return; @@ -219,7 +219,8 @@ - (void)createReactHostIfNeeded turboModuleManagerDelegate:_turboModuleManagerDelegate jsEngineProvider:^std::shared_ptr() { return [weakSelf createJSRuntimeFactory]; - }]; + } + launchOptions:launchOptions]; [_reactHost setBundleURLProvider:^NSURL *() { return [weakSelf bundleURL]; }]; diff --git a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm index 3fa06c43979bfd..e11217da70468b 100644 --- a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm +++ b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm @@ -8,6 +8,7 @@ #import #import +#import #import #import #import @@ -153,12 +154,15 @@ - (void)handleOpenURLNotification:(NSNotification *)notification RCT_EXPORT_METHOD(getInitialURL : (RCTPromiseResolveBlock)resolve reject : (__unused RCTPromiseRejectBlock)reject) { + RCTBridge *bridge = self.bridge; + if (!bridge) { + bridge = [RCTBridge currentBridge]; + } NSURL *initialURL = nil; - if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) { - initialURL = self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]; + if (bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) { + initialURL = bridge.launchOptions[UIApplicationLaunchOptionsURLKey]; } else { - NSDictionary *userActivityDictionary = - self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]; + NSDictionary *userActivityDictionary = bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]; if ([userActivityDictionary[UIApplicationLaunchOptionsUserActivityTypeKey] isEqual:NSUserActivityTypeBrowsingWeb]) { initialURL = ((NSUserActivity *)userActivityDictionary[@"UIApplicationLaunchOptionsUserActivityKey"]).webpageURL; } diff --git a/packages/react-native/React/Base/RCTBridgeProxy.h b/packages/react-native/React/Base/RCTBridgeProxy.h index 3a6de36473ee5b..2967514e578674 100644 --- a/packages/react-native/React/Base/RCTBridgeProxy.h +++ b/packages/react-native/React/Base/RCTBridgeProxy.h @@ -22,7 +22,8 @@ callableJSModules:(RCTCallableJSModules *)callableJSModules dispatchToJSThread:(void (^)(dispatch_block_t))dispatchToJSThread registerSegmentWithId:(void (^)(NSNumber *, NSString *))registerSegmentWithId - runtime:(void *)runtime NS_DESIGNATED_INITIALIZER; + runtime:(void *)runtime + launchOptions:(nullable NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER; - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel; - (void)forwardInvocation:(NSInvocation *)invocation; diff --git a/packages/react-native/React/Base/RCTBridgeProxy.mm b/packages/react-native/React/Base/RCTBridgeProxy.mm index 27637daf654c1c..5b3e0656929ee3 100644 --- a/packages/react-native/React/Base/RCTBridgeProxy.mm +++ b/packages/react-native/React/Base/RCTBridgeProxy.mm @@ -35,6 +35,7 @@ @implementation RCTBridgeProxy { RCTModuleRegistry *_moduleRegistry; RCTBundleManager *_bundleManager; RCTCallableJSModules *_callableJSModules; + NSDictionary *_launchOptions; void (^_dispatchToJSThread)(dispatch_block_t); void (^_registerSegmentWithId)(NSNumber *, NSString *); void *_runtime; @@ -47,6 +48,7 @@ - (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry dispatchToJSThread:(void (^)(dispatch_block_t))dispatchToJSThread registerSegmentWithId:(void (^)(NSNumber *, NSString *))registerSegmentWithId runtime:(void *)runtime + launchOptions:(nullable NSDictionary *)launchOptions { self = [super self]; if (self) { @@ -57,6 +59,7 @@ - (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry _dispatchToJSThread = dispatchToJSThread; _registerSegmentWithId = registerSegmentWithId; _runtime = runtime; + _launchOptions = [launchOptions copy]; } return self; } @@ -191,8 +194,7 @@ - (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path - (NSDictionary *)launchOptions { - [self logError:@"This method is not supported. Returning nil." cmd:_cmd]; - return nil; + return _launchOptions; } - (BOOL)loading diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h index ea4492980f976f..8f3c0460f38ed8 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h @@ -48,7 +48,8 @@ typedef std::shared_ptr (^RCTHostJSEngineProv - (instancetype)initWithBundleURL:(NSURL *)bundleURL hostDelegate:(id)hostDelegate turboModuleManagerDelegate:(id)turboModuleManagerDelegate - jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider NS_DESIGNATED_INITIALIZER; + jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider + launchOptions:(nullable NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER; @property (nonatomic, weak, nullable) id runtimeDelegate; diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm index 4547a0daee19fc..eb699d89d2e7f5 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm @@ -58,6 +58,8 @@ @implementation RCTHost { RCTHostBundleURLProvider _bundleURLProvider; RCTHostJSEngineProvider _jsEngineProvider; + NSDictionary *_launchOptions; + // All the surfaces that need to be started after main bundle execution NSMutableArray *_surfaceStartBuffer; std::mutex _surfaceStartBufferMutex; @@ -85,6 +87,7 @@ - (instancetype)initWithBundleURL:(NSURL *)bundleURL hostDelegate:(id)hostDelegate turboModuleManagerDelegate:(id)turboModuleManagerDelegate jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider + launchOptions:(nullable NSDictionary *)launchOptions { if (self = [super init]) { _hostDelegate = hostDelegate; @@ -93,6 +96,7 @@ - (instancetype)initWithBundleURL:(NSURL *)bundleURL _bundleManager = [RCTBundleManager new]; _moduleRegistry = [RCTModuleRegistry new]; _jsEngineProvider = [jsEngineProvider copy]; + _launchOptions = [launchOptions copy]; __weak RCTHost *weakSelf = self; @@ -204,7 +208,8 @@ - (void)start turboModuleManagerDelegate:_turboModuleManagerDelegate onInitialBundleLoad:_onInitialBundleLoad moduleRegistry:_moduleRegistry - parentInspectorTarget:_inspectorTarget.get()]; + parentInspectorTarget:_inspectorTarget.get() + launchOptions:_launchOptions]; [_hostDelegate hostDidStart:self]; } @@ -284,7 +289,8 @@ - (void)didReceiveReloadCommand turboModuleManagerDelegate:_turboModuleManagerDelegate onInitialBundleLoad:_onInitialBundleLoad moduleRegistry:_moduleRegistry - parentInspectorTarget:_inspectorTarget.get()]; + parentInspectorTarget:_inspectorTarget.get() + launchOptions:_launchOptions]; [_hostDelegate hostDidStart:self]; for (RCTFabricSurface *surface in [self _getAttachedSurfaces]) { diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h index 90d6911ce8be1e..e66e2b2bb37b70 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h @@ -62,7 +62,8 @@ typedef void (^_Null_unspecified RCTInstanceInitialBundleLoadCompletionBlock)(); turboModuleManagerDelegate:(id)turboModuleManagerDelegate onInitialBundleLoad:(RCTInstanceInitialBundleLoadCompletionBlock)onInitialBundleLoad moduleRegistry:(RCTModuleRegistry *)moduleRegistry - parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget; + parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget + launchOptions:(nullable NSDictionary *)launchOptions; - (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args; diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm index 7b30e83c17f290..0b16f13406f00f 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm @@ -84,6 +84,7 @@ @implementation RCTInstance { std::mutex _invalidationMutex; std::atomic _valid; RCTJSThreadManager *_jsThreadManager; + NSDictionary *_launchOptions; // APIs supporting interop with native modules and view managers RCTBridgeModuleDecorator *_bridgeModuleDecorator; @@ -100,6 +101,7 @@ - (instancetype)initWithDelegate:(id)delegate onInitialBundleLoad:(RCTInstanceInitialBundleLoadCompletionBlock)onInitialBundleLoad moduleRegistry:(RCTModuleRegistry *)moduleRegistry parentInspectorTarget:(jsinspector_modern::HostTarget *)parentInspectorTarget + launchOptions:(nullable NSDictionary *)launchOptions { if (self = [super init]) { _performanceLogger = [RCTPerformanceLogger new]; @@ -125,6 +127,7 @@ - (instancetype)initWithDelegate:(id)delegate [weakSelf callFunctionOnJSModule:moduleName method:methodName args:args]; }]; } + _launchOptions = launchOptions; NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; @@ -277,7 +280,8 @@ - (void)_start [strongSelf registerSegmentWithId:segmentId path:path]; } } - runtime:_reactInstance->getJavaScriptContext()]; + runtime:_reactInstance->getJavaScriptContext() + launchOptions:_launchOptions]; bridgeProxy.jsCallInvoker = jsCallInvoker; [RCTBridge setCurrentBridge:(RCTBridge *)bridgeProxy];