diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 3af1a19767cb8d..b1ed41cdc385e6 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -151,8 +151,12 @@ RCT_EXTERN void RCTEnableJSINativeModule(BOOL enabled); * lazily instantiated, so calling these methods for the first time with a given * module name/class may cause the class to be sychronously instantiated, * potentially blocking both the calling thread and main thread for a short time. + * + * Note: This method does NOT lazily load the particular module if it's not yet loaded. */ - (id)moduleForName:(NSString *)moduleName; +- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad; +// Note: This method lazily load the module as necessary. - (id)moduleForClass:(Class)moduleClass; /** diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index a8a79a9456c98e..22c9a07d5de78c 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -241,6 +241,11 @@ - (id)moduleForName:(NSString *)moduleName return [self.batchedBridge moduleForName:moduleName]; } +- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad +{ + return [self.batchedBridge moduleForName:moduleName lazilyLoadIfNecessary:lazilyLoad]; +} + - (id)moduleForClass:(Class)moduleClass { id module = [self.batchedBridge moduleForClass:moduleClass]; diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 9f42541df8f41f..79990b762d4eec 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -439,24 +439,38 @@ - (id)moduleForName:(NSString *)moduleName return _moduleDataByName[moduleName].instance; } -- (BOOL)moduleIsInitialized:(Class)moduleClass +- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad { - return _moduleDataByName[RCTBridgeModuleNameForClass(moduleClass)].hasInstance; -} + if (!lazilyLoad) { + return [self moduleForName:moduleName]; + } -- (id)moduleForClass:(Class)moduleClass -{ - NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass); RCTModuleData *moduleData = _moduleDataByName[moduleName]; if (moduleData) { return moduleData.instance; } // Module may not be loaded yet, so attempt to force load it here. - RCTAssert([moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], @"Asking for a NativeModule that doesn't conform to RCTBridgeModule: %@", NSStringFromClass(moduleClass)); - [self registerAdditionalModuleClasses:@[moduleClass]]; + const BOOL result = [self.delegate respondsToSelector:@selector(bridge:didNotFindModule:)] && + [self.delegate bridge:self didNotFindModule:moduleName]; + if (result) { + // Try again. + moduleData = _moduleDataByName[moduleName]; + } else { + RCTLogError(@"Unable to find module for %@", moduleName); + } - return _moduleDataByName[moduleName].instance; + return moduleData.instance; +} + +- (BOOL)moduleIsInitialized:(Class)moduleClass +{ + return _moduleDataByName[RCTBridgeModuleNameForClass(moduleClass)].hasInstance; +} + +- (id)moduleForClass:(Class)moduleClass +{ + return [self moduleForName:RCTBridgeModuleNameForClass(moduleClass) lazilyLoadIfNecessary:YES]; } - (std::shared_ptr)_buildModuleRegistryUnlocked