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:
Родитель
c9f869f9c7
Коммит
448db78a88
|
@ -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,6 +48,7 @@ RCT_EXPORT_METHOD(loadBundle
|
|||
: (RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *sourceURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForSplitBundleRoot:bundlePath];
|
||||
if (_bridge) {
|
||||
[_bridge loadAndExecuteSplitBundleURL:sourceURL
|
||||
onError:^(NSError *error) {
|
||||
reject(@"E_BUNDLE_LOAD_ERROR", [error localizedDescription], error);
|
||||
|
@ -53,6 +56,24 @@ RCT_EXPORT_METHOD(loadBundle
|
|||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче