/* * 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 #import #import #import #import "RCTAppDelegate+Protected.h" #import "RCTAppSetupUtils.h" #if RN_DISABLE_OSS_PLUGIN_HEADER #import #else #import #endif #import #import #import #import #import #import #import #if USE_HERMES #import #else #import #endif #import #import #import #import #import #import #import @interface RCTAppDelegate () @end @implementation RCTAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self _setUpFeatureFlags]; RCTSetNewArchEnabled([self newArchEnabled]); RCTAppSetupPrepareApp(application, self.turboModuleEnabled); self.rootViewFactory = [self createRCTRootViewFactory]; UIView *rootView = [self.rootViewFactory viewWithModuleName:self.moduleName initialProperties:self.initialProps launchOptions:launchOptions]; if (self.newArchEnabled || self.fabricEnabled) { [RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self; } [self _logWarnIfCreateRootViewWithBridgeIsOverridden]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [self createRootViewController]; [self setRootView:rootView toRootViewController:rootViewController]; self.window.rootViewController = rootViewController; self.window.windowScene.delegate = self; [self.window makeKeyAndVisible]; return YES; } - (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; } // TODO T173939093 - Remove _logWarnIfCreateRootViewWithBridgeIsOverridden after 0.74 is cut - (void)_logWarnIfCreateRootViewWithBridgeIsOverridden { SEL selector = @selector(createRootViewWithBridge:moduleName:initProps:); IMP baseClassImp = method_getImplementation(class_getInstanceMethod([RCTAppDelegate class], selector)); IMP currentClassImp = method_getImplementation(class_getInstanceMethod([self class], selector)); if (currentClassImp != baseClassImp) { NSString *warnMessage = @"If you are using the `createRootViewWithBridge` to customize the root view appearence," "for example to set the backgroundColor, please migrate to `customiseView` method.\n" "The `createRootViewWithBridge` method is not invoked in bridgeless."; RCTLogWarn(@"%@", warnMessage); } } - (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]; } #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 - 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 nullptr; } - (std::shared_ptr)getTurboModule:(const std::string &)name initParams: (const facebook::react::ObjCTurboModule::InitParams &)params { return nullptr; } - (id)getModuleInstanceFromClass:(Class)moduleClass { return RCTAppSetupDefaultModuleFromClass(moduleClass); } #pragma mark - RCTComponentViewFactoryComponentProvider - (NSDictionary> *)thirdPartyFabricComponents { return @{}; } - (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]; }; return [[RCTRootViewFactory alloc] initWithConfiguration:configuration andTurboModuleManagerDelegate:self]; } #pragma mark - Feature Flags class RCTAppDelegateBridgelessFeatureFlags : public facebook::react::ReactNativeFeatureFlagsDefaults { public: bool useModernRuntimeScheduler() override { return true; } bool enableMicrotasks() override { return true; } bool batchRenderingUpdatesInEventLoop() override { return true; } }; - (void)_setUpFeatureFlags { if ([self bridgelessEnabled]) { facebook::react::ReactNativeFeatureFlags::override(std::make_unique()); } } @end