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
This commit is contained in:
Peter Argany 2020-07-23 17:09:20 -07:00 коммит произвёл Facebook GitHub Bot
Родитель c9f869f9c7
Коммит 448db78a88
3 изменённых файлов: 52 добавлений и 10 удалений

Просмотреть файл

@ -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 <NSObject>
@property (nonatomic, copy, nonnull) void (^loadScript)(RCTSource *source);
@end

Просмотреть файл

@ -6,7 +6,8 @@
*/
#import <React/RCTBridgeModule.h>
#import <React/RCTJSScriptLoaderModule.h>
#import <UIKit/UIKit.h>
@interface RCTDevSplitBundleLoader : NSObject <RCTBridgeModule>
@interface RCTDevSplitBundleLoader : NSObject <RCTBridgeModule, RCTJSScriptLoaderModule>
@end

Просмотреть файл

@ -12,6 +12,7 @@
#import <React/RCTBundleURLProvider.h>
#import <React/RCTConvert.h>
#import <React/RCTDefines.h>
#import <React/RCTDevSettings.h>
#import <React/RCTUtils.h>
#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<TurboModule>)getTurboModule:(const ObjCTurboModule::InitParams &)params
@ -66,6 +87,8 @@ RCT_EXPORT_METHOD(loadBundle
@implementation RCTDevSplitBundleLoader
@synthesize loadScript = _loadScript;
+ (NSString *)moduleName
{
return nil;