/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #import "RCTAppDelegate.h" #import #import #import #import #import #import #include #import #import #import #import #import "RCTAppDelegate+Protected.h" #import "RCTAppSetupUtils.h" #import "RCTDependencyProvider.h" #if RN_DISABLE_OSS_PLUGIN_HEADER #import #else #import #endif #import #import #if USE_HERMES #import #else #import #endif #import using namespace facebook::react; @interface RCTAppDelegate () @end @implementation RCTAppDelegate - (instancetype)init { if (self = [super init]) { _automaticallyLoadReactNativeWindow = YES; } return self; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self _setUpFeatureFlags]; RCTSetNewArchEnabled([self newArchEnabled]); [RCTColorSpaceUtils applyDefaultColorSpace:self.defaultColorSpace]; RCTAppSetupPrepareApp(application, self.turboModuleEnabled); self.rootViewFactory = [self createRCTRootViewFactory]; if (self.newArchEnabled || self.fabricEnabled) { [RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self; } if (self.automaticallyLoadReactNativeWindow) { [self loadReactNativeWindow:launchOptions]; } return YES; } - (void)loadReactNativeWindow:(NSDictionary *)launchOptions { UIView *rootView = [self.rootViewFactory viewWithModuleName:self.moduleName initialProperties:self.initialProps launchOptions:launchOptions]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [self createRootViewController]; [self setRootView:rootView toRootViewController:rootViewController]; _window.windowScene.delegate = self; _window.rootViewController = rootViewController; [_window makeKeyAndVisible]; } - (void)applicationDidEnterBackground:(UIApplication *)application { // Noop } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { [NSException raise:@"RCTBridgeDelegate::sourceURLForBridge not implemented" format:@"Subclasses must implement a valid sourceURLForBridge method"]; return nil; } - (RCTBridge *)createBridgeWithDelegate:(id)delegate launchOptions:(NSDictionary *)launchOptions { return [[RCTBridge alloc] initWithDelegate:delegate launchOptions:launchOptions]; } - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initProps:(NSDictionary *)initProps { BOOL enableFabric = self.fabricEnabled; UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric); rootView.backgroundColor = [UIColor systemBackgroundColor]; return rootView; } - (UIViewController *)createRootViewController { return [UIViewController new]; } - (void)setRootView:(UIView *)rootView toRootViewController:(UIViewController *)rootViewController { rootViewController.view = rootView; } - (void)customizeRootView:(RCTRootView *)rootView { // Override point for customization after application launch. } #pragma mark - UISceneDelegate - (void)windowScene:(UIWindowScene *)windowScene didUpdateCoordinateSpace:(id)previousCoordinateSpace interfaceOrientation:(UIInterfaceOrientation)previousInterfaceOrientation traitCollection:(UITraitCollection *)previousTraitCollection API_AVAILABLE(ios(13.0)) { [[NSNotificationCenter defaultCenter] postNotificationName:RCTWindowFrameDidChangeNotification object:self]; } - (RCTColorSpace)defaultColorSpace { return RCTColorSpaceSRGB; } #pragma mark - New Arch Enabled settings - (BOOL)newArchEnabled { #if RCT_NEW_ARCH_ENABLED return YES; #else return NO; #endif } - (BOOL)turboModuleEnabled { return [self newArchEnabled]; } - (BOOL)fabricEnabled { return [self newArchEnabled]; } - (BOOL)bridgelessEnabled { return [self newArchEnabled]; } - (NSURL *)bundleURL { [NSException raise:@"RCTAppDelegate::bundleURL not implemented" format:@"Subclasses must implement a valid getBundleURL method"]; return nullptr; } #pragma mark - RCTHostDelegate - (void)hostDidStart:(RCTHost *)host { } #pragma mark - Bridge and Bridge Adapter properties - (RCTBridge *)bridge { return self.rootViewFactory.bridge; } - (RCTSurfacePresenterBridgeAdapter *)bridgeAdapter { return self.rootViewFactory.bridgeAdapter; } - (void)setBridge:(RCTBridge *)bridge { self.rootViewFactory.bridge = bridge; } - (void)setBridgeAdapter:(RCTSurfacePresenterBridgeAdapter *)bridgeAdapter { self.rootViewFactory.bridgeAdapter = bridgeAdapter; } #pragma mark - RCTTurboModuleManagerDelegate - (Class)getModuleClassFromName:(const char *)name { #if RN_DISABLE_OSS_PLUGIN_HEADER return RCTTurboModulePluginClassProvider(name); #else return RCTCoreModulesClassProvider(name); #endif } - (std::shared_ptr)getTurboModule:(const std::string &)name jsInvoker:(std::shared_ptr)jsInvoker { return DefaultTurboModules::getTurboModule(name, jsInvoker); } - (std::shared_ptr)getTurboModule:(const std::string &)name initParams:(const ObjCTurboModule::InitParams &)params { return nullptr; } - (id)getModuleInstanceFromClass:(Class)moduleClass { return RCTAppSetupDefaultModuleFromClass(moduleClass, self.dependencyProvider); } #pragma mark - RCTComponentViewFactoryComponentProvider - (NSDictionary> *)thirdPartyFabricComponents { return self.dependencyProvider ? self.dependencyProvider.thirdPartyFabricComponents : @{}; } - (RCTRootViewFactory *)createRCTRootViewFactory { __weak __typeof(self) weakSelf = self; RCTBundleURLBlock bundleUrlBlock = ^{ RCTAppDelegate *strongSelf = weakSelf; return strongSelf.bundleURL; }; RCTRootViewFactoryConfiguration *configuration = [[RCTRootViewFactoryConfiguration alloc] initWithBundleURLBlock:bundleUrlBlock newArchEnabled:self.fabricEnabled turboModuleEnabled:self.turboModuleEnabled bridgelessEnabled:self.bridgelessEnabled]; configuration.createRootViewWithBridge = ^UIView *(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps) { return [weakSelf createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps]; }; configuration.createBridgeWithDelegate = ^RCTBridge *(id delegate, NSDictionary *launchOptions) { return [weakSelf createBridgeWithDelegate:delegate launchOptions:launchOptions]; }; configuration.customizeRootView = ^(UIView *_Nonnull rootView) { [weakSelf customizeRootView:(RCTRootView *)rootView]; }; configuration.sourceURLForBridge = ^NSURL *_Nullable(RCTBridge *_Nonnull bridge) { return [weakSelf sourceURLForBridge:bridge]; }; if ([self respondsToSelector:@selector(extraModulesForBridge:)]) { configuration.extraModulesForBridge = ^NSArray> *_Nonnull(RCTBridge *_Nonnull bridge) { return [weakSelf extraModulesForBridge:bridge]; }; } if ([self respondsToSelector:@selector(extraLazyModuleClassesForBridge:)]) { configuration.extraLazyModuleClassesForBridge = ^NSDictionary *_Nonnull(RCTBridge *_Nonnull bridge) { return [weakSelf extraLazyModuleClassesForBridge:bridge]; }; } if ([self respondsToSelector:@selector(bridge:didNotFindModule:)]) { configuration.bridgeDidNotFindModule = ^BOOL(RCTBridge *_Nonnull bridge, NSString *_Nonnull moduleName) { return [weakSelf bridge:bridge didNotFindModule:moduleName]; }; } return [[RCTRootViewFactory alloc] initWithTurboModuleDelegate:self hostDelegate:self configuration:configuration]; } #pragma mark - Feature Flags class RCTAppDelegateBridgelessFeatureFlags : public ReactNativeFeatureFlagsDefaults { public: bool enableBridgelessArchitecture() override { return true; } bool enableFabricRenderer() override { return true; } bool useTurboModules() override { return true; } bool useNativeViewConfigsInBridgelessMode() override { return true; } bool enableFixForViewCommandRace() override { return true; } }; - (void)_setUpFeatureFlags { if ([self bridgelessEnabled]) { ReactNativeFeatureFlags::override(std::make_unique()); } } @end