From 448db78a88a64009e930fc93710d592ae13943fa Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Thu, 23 Jul 2020 17:09:20 -0700 Subject: [PATCH] Fix loading from Metro in Bridgeless mode (#29453) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/29453 Problem Statement: A native module needs to call a function on `ReactInstance` (in this case `loadScript`). Typically, this is handled by the bridge. Current Bridgeless Solution: Create a new protocol (in this case `RCTJSScriptLoaderModule`) which lets a block be passed in TM init to forward the method call to `ReactInstance`. This is the best thing I could think of right now. Changelog:[Internal] Reviewed By: RSNara Differential Revision: D22512748 fbshipit-source-id: e6559279b6e299e17d1199407129ad3902c41e6b --- React/Base/RCTJSScriptLoaderModule.h | 18 +++++++++ React/CoreModules/RCTDevSplitBundleLoader.h | 3 +- React/CoreModules/RCTDevSplitBundleLoader.mm | 41 +++++++++++++++----- 3 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 React/Base/RCTJSScriptLoaderModule.h diff --git a/React/Base/RCTJSScriptLoaderModule.h b/React/Base/RCTJSScriptLoaderModule.h new file mode 100644 index 00000000000..a0ba36ed7dc --- /dev/null +++ b/React/Base/RCTJSScriptLoaderModule.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +@class RCTSource; + +/** + * This protocol should be adopted when a turbo module needs to tell React Native to load a script. + * In bridge-less React Native, it is a replacement for [_bridge loadAndExecuteSplitBundleURL:]. + */ +@protocol RCTJSScriptLoaderModule + +@property (nonatomic, copy, nonnull) void (^loadScript)(RCTSource *source); + +@end diff --git a/React/CoreModules/RCTDevSplitBundleLoader.h b/React/CoreModules/RCTDevSplitBundleLoader.h index c32f60d9750..52a115c12a8 100644 --- a/React/CoreModules/RCTDevSplitBundleLoader.h +++ b/React/CoreModules/RCTDevSplitBundleLoader.h @@ -6,7 +6,8 @@ */ #import +#import #import -@interface RCTDevSplitBundleLoader : NSObject +@interface RCTDevSplitBundleLoader : NSObject @end diff --git a/React/CoreModules/RCTDevSplitBundleLoader.mm b/React/CoreModules/RCTDevSplitBundleLoader.mm index 73d0c98e692..4a2243e17c2 100644 --- a/React/CoreModules/RCTDevSplitBundleLoader.mm +++ b/React/CoreModules/RCTDevSplitBundleLoader.mm @@ -12,6 +12,7 @@ #import #import #import +#import #import #import "CoreModulesPlugins.h" @@ -23,10 +24,11 @@ using namespace facebook::react; #if RCT_DEV_MENU -@implementation RCTDevSplitBundleLoader { -} +@implementation RCTDevSplitBundleLoader @synthesize bridge = _bridge; +@synthesize loadScript = _loadScript; +@synthesize turboModuleRegistry = _turboModuleRegistry; RCT_EXPORT_MODULE() @@ -46,13 +48,32 @@ RCT_EXPORT_METHOD(loadBundle : (RCTPromiseRejectBlock)reject) { NSURL *sourceURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForSplitBundleRoot:bundlePath]; - [_bridge loadAndExecuteSplitBundleURL:sourceURL - onError:^(NSError *error) { - reject(@"E_BUNDLE_LOAD_ERROR", [error localizedDescription], error); - } - onComplete:^() { - resolve(@YES); - }]; + if (_bridge) { + [_bridge loadAndExecuteSplitBundleURL:sourceURL + onError:^(NSError *error) { + reject(@"E_BUNDLE_LOAD_ERROR", [error localizedDescription], error); + } + onComplete:^() { + resolve(@YES); + }]; + } else { + __weak __typeof(self) weakSelf = self; + [RCTJavaScriptLoader loadBundleAtURL:sourceURL + onProgress:^(RCTLoadingProgress *progressData) { + // TODO: Setup loading bar. + } + onComplete:^(NSError *error, RCTSource *source) { + if (error) { + reject(@"E_BUNDLE_LOAD_ERROR", [error localizedDescription], error); + return; + } + __typeof(self) strongSelf = weakSelf; + strongSelf->_loadScript(source); + RCTDevSettings *devSettings = [strongSelf->_turboModuleRegistry moduleForName:"RCTDevSettings"]; + [devSettings setupHMRClientWithAdditionalBundleURL:source.url]; + resolve(@YES); + }]; + } } - (std::shared_ptr)getTurboModule:(const ObjCTurboModule::InitParams &)params @@ -66,6 +87,8 @@ RCT_EXPORT_METHOD(loadBundle @implementation RCTDevSplitBundleLoader +@synthesize loadScript = _loadScript; + + (NSString *)moduleName { return nil;