diff --git a/Libraries/AppDelegate/RCTAppDelegate.h b/Libraries/AppDelegate/RCTAppDelegate.h index 0734f10df0..0bca647e17 100644 --- a/Libraries/AppDelegate/RCTAppDelegate.h +++ b/Libraries/AppDelegate/RCTAppDelegate.h @@ -35,7 +35,12 @@ * If you need to customize the default implementation, you can invoke `[super ]` and use the returned object. * - * Overridable methods (New Architecture): + * Overridable methods + * Shared: + * - (RCTBridge *)createBridgeWithDelegate:(id)delegate launchOptions:(NSDictionary *)launchOptions; + * - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString*)moduleName initProps:(NSDictionary *)initProps; + * - (UIViewController *)createRootViewController; + * New Architecture: * - (BOOL)concurrentRootEnabled * - (NSDictionary *)prepareInitialProps * - (Class)getModuleClassFromName:(const char *)name @@ -53,6 +58,41 @@ @property (nonatomic, strong) RCTBridge *bridge; @property (nonatomic, strong) NSString *moduleName; +/** + * It creates a `RCTBridge` using a delegate and some launch options. + * By default, it is invoked passing `self` as a delegate. + * You can override this function to customize the logic that creates the RCTBridge + * + * @parameter: delegate - an object that implements the `RCTBridgeDelegate` protocol. + * @parameter: launchOptions - a dictionary with a set of options. + * + * @returns: a newly created instance of RCTBridge. + */ +- (RCTBridge *)createBridgeWithDelegate:(id)delegate launchOptions:(NSDictionary *)launchOptions; + +/** + * It creates a `UIView` starting from a bridge, a module name and a set of initial properties. + * By default, it is invoked using the bridge created by `createBridgeWithDelegate:launchOptions` and + * the name in the `self.moduleName` variable. + * You can override this function to customize the logic that creates the Root View. + * + * @parameter: bridge - an instance of the `RCTBridge` object. + * @parameter: moduleName - the name of the app, used by Metro to resolve the module. + * @parameter: initProps - a set of initial properties. + * + * @returns: a UIView properly configured with a bridge for React Native. + */ +- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString*)moduleName initProps:(NSDictionary *)initProps; + +/** + * It creates the RootViewController. + * By default, it creates a new instance of a `UIViewController`. + * You can override it to provide your own initial ViewController. + * + * @return: an instance of `UIViewController`. + */ +- (UIViewController *)createRootViewController; + @end #if RCT_NEW_ARCH_ENABLED diff --git a/Libraries/AppDelegate/RCTAppDelegate.mm b/Libraries/AppDelegate/RCTAppDelegate.mm index b08f46e2f0..b0e79fa138 100644 --- a/Libraries/AppDelegate/RCTAppDelegate.mm +++ b/Libraries/AppDelegate/RCTAppDelegate.mm @@ -32,7 +32,7 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot"; RCTAppSetupPrepareApp(application); if (!self.bridge) { - self.bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; + self.bridge = [self createBridgeWithDelegate:self launchOptions:launchOptions]; } #if RCT_NEW_ARCH_ENABLED _contextContainer = std::make_shared(); @@ -43,7 +43,7 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot"; #endif NSDictionary *initProps = [self prepareInitialProps]; - UIView *rootView = RCTAppSetupDefaultRootView(self.bridge, self.moduleName, initProps); + UIView *rootView = [self createRootViewWithBridge:self.bridge moduleName:self.moduleName initProps:initProps]; if (@available(iOS 13.0, *)) { rootView.backgroundColor = [UIColor systemBackgroundColor]; @@ -52,7 +52,7 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot"; } self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [UIViewController new]; + UIViewController *rootViewController = [self createRootViewController]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; @@ -88,6 +88,21 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot"; return initProps; } +- (RCTBridge *)createBridgeWithDelegate:(id)delegate launchOptions:(NSDictionary *)launchOptions +{ + return [[RCTBridge alloc] initWithDelegate:delegate launchOptions:launchOptions]; +} + +- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString*)moduleName initProps:(NSDictionary *)initProps +{ + return RCTAppSetupDefaultRootView(bridge, moduleName, initProps); +} + +- (UIViewController *)createRootViewController +{ + return [UIViewController new]; +} + #if RCT_NEW_ARCH_ENABLED #pragma mark - RCTCxxBridgeDelegate