Skip to content

Commit

Permalink
fix(iOS): add missing forward blocks to RCTRootViewFactory (#43526)
Browse files Browse the repository at this point in the history
Summary:
This PR adds missing forwarding blocks to RCTRootViewFactory, currently when a user tries to override `sourceURLForBridge` in AppDelegate it isn't overridden.

## Changelog:

[IOS] [FIXED] - add missing forward blocks to RCTRootViewFactory

Pull Request resolved: #43526

Test Plan: Override: `extraModulesForBridge`, `extraLazyModuleClassesForBridge`, `bridge didNotFindModule`,  `sourceURLForBridge:` methods in AppDelegate and check if they are called on old architecture

Reviewed By: philIip

Differential Revision: D55186872

Pulled By: cortinico

fbshipit-source-id: 5988c7bab1439ccc4885b7337336c1e120ba9ea6
  • Loading branch information
okwasniewski authored and facebook-github-bot committed Mar 21, 2024
1 parent 1021448 commit 9d79f05
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
19 changes: 19 additions & 0 deletions packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,25 @@ - (RCTRootViewFactory *)createRCTRootViewFactory
return [weakSelf createBridgeWithDelegate:delegate launchOptions:launchOptions];
};

configuration.sourceURLForBridge = ^NSURL *_Nullable(RCTBridge *_Nonnull bridge)
{
return [weakSelf sourceURLForBridge:bridge];
};

configuration.extraModulesForBridge = ^NSArray<id<RCTBridgeModule>> *_Nonnull(RCTBridge *_Nonnull bridge)
{
return [weakSelf extraModulesForBridge:bridge];
};

configuration.extraLazyModuleClassesForBridge = ^NSDictionary<NSString *, Class> *_Nonnull(RCTBridge *_Nonnull bridge)
{
return [weakSelf extraLazyModuleClassesForBridge:bridge];
};

configuration.bridgeDidNotFindModule = ^BOOL(RCTBridge *_Nonnull bridge, NSString *_Nonnull moduleName) {
return [weakSelf bridge:bridge didNotFindModule:moduleName];
};

return [[RCTRootViewFactory alloc] initWithConfiguration:configuration andTurboModuleManagerDelegate:self];
}

Expand Down
42 changes: 42 additions & 0 deletions packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ typedef UIView *_Nonnull (
^RCTCreateRootViewWithBridgeBlock)(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps);
typedef RCTBridge *_Nonnull (
^RCTCreateBridgeWithDelegateBlock)(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions);
typedef NSURL *_Nullable (^RCTSourceURLForBridgeBlock)(RCTBridge *bridge);
typedef NSArray<id<RCTBridgeModule>> *_Nonnull (^RCTExtraModulesForBridgeBlock)(RCTBridge *bridge);
typedef NSDictionary<NSString *, Class> *_Nonnull (^RCTExtraLazyModuleClassesForBridge)(RCTBridge *bridge);
typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *moduleName);

#pragma mark - RCTRootViewFactory Configuration
@interface RCTRootViewFactoryConfiguration : NSObject
Expand Down Expand Up @@ -81,6 +85,44 @@ typedef RCTBridge *_Nonnull (
*/
@property (nonatomic, nullable) RCTCreateBridgeWithDelegateBlock createBridgeWithDelegate;

/**
* Block that returns the location of the JavaScript source file. When running from the packager
* this should be an absolute URL, e.g. `http://localhost:8081/index.ios.bundle`.
* When running from a locally bundled JS file, this should be a `file://` url
* pointing to a path inside the app resources, e.g. `file://.../main.jsbundle`.
*/
@property (nonatomic, nullable) RCTSourceURLForBridgeBlock sourceURLForBridge;

/**
* The bridge initializes any registered RCTBridgeModules automatically, however
* if you wish to instantiate your own module instances, you can return them
* from this block.
*
* Note: You should always return a new instance for each call, rather than
* returning the same instance each time the bridge is reloaded. Module instances
* should not be shared between bridges, and this may cause unexpected behavior.
*
* It is also possible to override standard modules with your own implementations
* by returning a class with the same `moduleName` from this method, but this is
* not recommended in most cases - if the module methods and behavior do not
* match exactly, it may lead to bugs or crashes.
*/
@property (nonatomic, nullable) RCTExtraModulesForBridgeBlock extraModulesForBridge;

/**
* Retrieve the list of lazy-native-modules names for the given bridge.
*/
@property (nonatomic, nullable) RCTExtraLazyModuleClassesForBridge extraLazyModuleClassesForBridge;

/**
* The bridge will call this block when a module been called from JS
* cannot be found among registered modules.
* It should return YES if the module with name 'moduleName' was registered
* in the implementation, and the system must attempt to look for it again among registered.
* If the module was not registered, return NO to prevent further searches.
*/
@property (nonatomic, nullable) RCTBridgeDidNotFindModuleBlock bridgeDidNotFindModule;

@end

#pragma mark - RCTRootViewFactory
Expand Down
27 changes: 27 additions & 0 deletions packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,38 @@ - (void)didCreateContextContainer:(std::shared_ptr<facebook::react::ContextConta
contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
}

- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
if (_configuration.extraModulesForBridge != nil) {
return _configuration.extraModulesForBridge(bridge);
}
return nil;
}

- (NSDictionary<NSString *, Class> *)extraLazyModuleClassesForBridge:(RCTBridge *)bridge
{
if (_configuration.extraLazyModuleClassesForBridge != nil) {
return _configuration.extraLazyModuleClassesForBridge(bridge);
}
return nil;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
if (_configuration.sourceURLForBridge != nil) {
return _configuration.sourceURLForBridge(bridge);
}
return [self bundleURL];
}

- (BOOL)bridge:(RCTBridge *)bridge didNotFindModule:(NSString *)moduleName
{
if (_configuration.bridgeDidNotFindModule != nil) {
return _configuration.bridgeDidNotFindModule(bridge, moduleName);
}
return NO;
}

- (NSURL *)bundleURL
{
return self->_configuration.bundleURL;
Expand Down

0 comments on commit 9d79f05

Please sign in to comment.