From 18f3de9dcea239bedcb87ea7ccf853905e259b2f Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Mon, 26 Nov 2018 17:26:08 -0800 Subject: [PATCH] Allow init of Native Module before bridge is initialized [2/N] Summary: This may be controversial. Right now, RelayPrefetcher is initialized [here](https://fburl.com/p01iunr1), after bridge is initialized. I want to create a FBRelayPrefetcherModule instance eagerly (diff 3 in stack), and then pass that into the bridge module registry. This way, native side gets to use RelayPrefetcher before bridge is init, and JS still accesses the same instance of FBRelayPrefetcherModule. The only other option is drastically change bridge init, to allow passing in some eagerly initialized instances. Reviewed By: shergin Differential Revision: D13164277 fbshipit-source-id: b45111cd68d78820e61e4fca7e54a7e8df32a3f0 --- React/Base/RCTBridge+Private.h | 9 +++++++-- React/Base/RCTBridge.m | 5 +++++ React/Base/RCTModuleData.h | 2 +- React/CxxBridge/RCTCxxBridge.mm | 11 +++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/React/Base/RCTBridge+Private.h b/React/Base/RCTBridge+Private.h index f72ea6fe2ee..2996d37946b 100644 --- a/React/Base/RCTBridge+Private.h +++ b/React/Base/RCTBridge+Private.h @@ -107,10 +107,15 @@ RCT_EXTERN void RCTRegisterModule(Class); - (RCTModuleData *)moduleDataForName:(NSString *)moduleName; /** -* Registers additional classes with the ModuleRegistry. -*/ + * Registers additional classes with the ModuleRegistry. + */ - (void)registerAdditionalModuleClasses:(NSArray *)newModules; +/** + * Updates the ModuleRegistry with a pre-initialized instance. + */ +- (void)updateModuleWithInstance:(id)instance; + /** * Systrace profiler toggling methods exposed for the RCTDevMenu */ diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index 98f4a497240..046925eef4c 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -361,6 +361,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) } } +- (void)updateModuleWithInstance:(id)instance +{ + [self.batchedBridge updateModuleWithInstance:instance]; +} + - (void)registerAdditionalModuleClasses:(NSArray *)modules { [self.batchedBridge registerAdditionalModuleClasses:modules]; diff --git a/React/Base/RCTModuleData.h b/React/Base/RCTModuleData.h index 844ea922ce6..a0602501cb1 100644 --- a/React/Base/RCTModuleData.h +++ b/React/Base/RCTModuleData.h @@ -69,7 +69,7 @@ typedef id(^RCTBridgeModuleProvider)(void); * if it has not already been created. To check if the module instance exists * without causing it to be created, use `hasInstance` instead. */ -@property (nonatomic, strong, readonly) id instance; +@property (nonatomic, strong, readwrite) id instance; /** * Returns the module method dispatch queue. Note that this will init both the diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 74ec4ec0325..6ecfe14acb4 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -547,6 +547,17 @@ struct RCTInstanceCallback : public InstanceCallback { _moduleRegistryCreated = YES; } +- (void)updateModuleWithInstance:(id)instance; +{ + NSString *const moduleName = RCTBridgeModuleNameForClass([instance class]); + if (moduleName) { + RCTModuleData *const moduleData = _moduleDataByName[moduleName]; + if (moduleData) { + moduleData.instance = instance; + } + } +} + - (NSArray *)registerModulesForClasses:(NSArray *)moduleClasses { return [self _registerModulesForClasses:moduleClasses lazilyDiscovered:NO];