first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
/*
* 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 <UIKit/UIKit.h>
#import "RCTDefaultReactNativeFactoryDelegate.h"
#import "RCTReactNativeFactory.h"
#import "RCTRootViewFactory.h"
@class RCTBridge;
@protocol RCTBridgeDelegate;
@protocol RCTComponentViewProtocol;
@class RCTRootView;
@class RCTSurfacePresenterBridgeAdapter;
@protocol RCTDependencyProvider;
NS_ASSUME_NONNULL_BEGIN
/**
* @deprecated RCTAppDelegate is deprecated and will be removed in a future version of React Native. Use
`RCTReactNativeFactory` instead.
*
* The RCTAppDelegate is an utility class that implements some base configurations for all the React Native apps.
* It is not mandatory to use it, but it could simplify your AppDelegate code.
*
* To use it, you just need to make your AppDelegate a subclass of RCTAppDelegate:
*
* ```objc
* #import <React/RCTAppDelegate.h>
* @interface AppDelegate: RCTAppDelegate
* @end
* ```
*
* All the methods implemented by the RCTAppDelegate can be overridden by your AppDelegate if you need to provide a
custom implementation.
* If you need to customize the default implementation, you can invoke `[super <method_name>]` and use the returned
object.
*
* Overridable methods
* Shared:
* - (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary
*)launchOptions;
* - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString*)moduleName initProps:(NSDictionary
*)initProps;
* - (UIViewController *)createRootViewController;
* - (void)setRootView:(UIView *)rootView toRootViewController:(UIViewController *)rootViewController;
* New Architecture:
* - (BOOL)turboModuleEnabled;
* - (BOOL)fabricEnabled;
* - (NSDictionary *)prepareInitialProps
* - (Class)getModuleClassFromName:(const char *)name
* - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
* - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
initParams:
(const facebook::react::ObjCTurboModule::InitParams &)params
* - (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
*/
__attribute__((deprecated(
"RCTAppDelegate is deprecated and will be removed in a future version of React Native. Use `RCTReactNativeFactory` instead.")))
@interface RCTAppDelegate : RCTDefaultReactNativeFactoryDelegate<UIApplicationDelegate>
/// The window object, used to render the UViewControllers
@property (nonatomic, strong, nonnull) UIWindow *window;
@property (nonatomic, nullable) RCTBridge *bridge
__attribute__((deprecated("The bridge is deprecated and will be removed when removing the legacy architecture.")));
@property (nonatomic, strong, nullable) NSString *moduleName;
@property (nonatomic, strong, nullable) NSDictionary *initialProps;
@property (nonatomic, strong) RCTReactNativeFactory *reactNativeFactory;
/// If `automaticallyLoadReactNativeWindow` is set to `true`, the React Native window will be loaded automatically.
@property (nonatomic, assign) BOOL automaticallyLoadReactNativeWindow;
@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter __attribute__((
deprecated("The bridge adapter is deprecated and will be removed when removing the legacy architecture.")));
;
- (RCTRootViewFactory *)rootViewFactory;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,90 @@
/*
* 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 <React/RCTBridgeDelegate.h>
#import <React/RCTLog.h>
#import <React/RCTRootView.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <React/RCTUtils.h>
#import <ReactCommon/RCTHost.h>
#include <UIKit/UIKit.h>
#import <objc/runtime.h>
#import "RCTAppSetupUtils.h"
#import "RCTDependencyProvider.h"
#if RN_DISABLE_OSS_PLUGIN_HEADER
#import <RCTTurboModulePlugin/RCTTurboModulePlugin.h>
#else
#import <React/CoreModulesPlugins.h>
#endif
#import <React/RCTComponentViewFactory.h>
#import <React/RCTComponentViewProtocol.h>
#import <react/nativemodule/defaults/DefaultTurboModules.h>
using namespace facebook::react;
@implementation RCTAppDelegate
- (instancetype)init
{
if (self = [super init]) {
_automaticallyLoadReactNativeWindow = YES;
}
return self;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.reactNativeFactory = [[RCTReactNativeFactory alloc] initWithDelegate: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.rootViewController = rootViewController;
[_window makeKeyAndVisible];
}
- (RCTRootViewFactory *)rootViewFactory
{
return self.reactNativeFactory.rootViewFactory;
}
- (RCTBridge *)bridge
{
return self.rootViewFactory.bridge;
}
- (RCTSurfacePresenterBridgeAdapter *)bridgeAdapter
{
return self.rootViewFactory.bridgeAdapter;
}
- (void)setBridge:(RCTBridge *)bridge
{
self.reactNativeFactory.rootViewFactory.bridge = bridge;
}
- (void)setBridgeAdapter:(RCTSurfacePresenterBridgeAdapter *)bridgeAdapter
{
self.reactNativeFactory.rootViewFactory.bridgeAdapter = bridgeAdapter;
}
@end

View File

@@ -0,0 +1,59 @@
/*
* 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 <Foundation/Foundation.h>
#import <React/RCTBridge.h>
#import <React/RCTRootView.h>
#ifdef __cplusplus
#import <memory>
#if USE_THIRD_PARTY_JSC != 1
#import <reacthermes/HermesExecutorFactory.h>
#endif
#import <ReactCommon/RCTTurboModuleManager.h>
#import <jsireact/JSIExecutor.h>
@protocol RCTDependencyProvider;
// Forward declaration to decrease compilation coupling
namespace facebook::react {
class RuntimeScheduler;
}
RCT_EXTERN NSArray<NSString *> *RCTAppSetupUnstableModulesRequiringMainQueueSetup(
id<RCTDependencyProvider> dependencyProvider);
RCT_EXTERN id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(
Class moduleClass,
id<RCTDependencyProvider> dependencyProvider);
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutorFactory(
RCTBridge *bridge,
RCTTurboModuleManager *turboModuleManager,
const std::shared_ptr<facebook::react::RuntimeScheduler> &runtimeScheduler);
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupJsExecutorFactoryForOldArch(
RCTBridge *bridge,
const std::shared_ptr<facebook::react::RuntimeScheduler> &runtimeScheduler)
__attribute__((deprecated(
"RCTAppSetupJsExecutorFactoryForOldArch(RCTBridge *, RuntimeScheduler) is deprecated and will be removed when we remove the legacy architecture.")));
;
#endif // __cplusplus
RCT_EXTERN_C_BEGIN
void RCTAppSetupPrepareApp(UIApplication *application, BOOL turboModuleEnabled) __attribute__((deprecated(
"RCTAppSetupPrepareApp(UIApplication, BOOL) is deprecated and it's signature will change when we remove the legacy arch")));
UIView *
RCTAppSetupDefaultRootView(RCTBridge *bridge, NSString *moduleName, NSDictionary *initialProperties, BOOL fabricEnabled)
__attribute__((deprecated(
"RCTAppSetupDefaultRootView(RCTBridge *, NSString *, NSDictionary *, BOOL) is deprecated and it's signature will change when we remove the legacy arch")));
RCT_EXTERN_C_END

View File

@@ -0,0 +1,179 @@
/*
* 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 "RCTAppSetupUtils.h"
#import <React/RCTJSIExecutorRuntimeInstaller.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
// Turbo Module
#import <React/RCTBundleAssetImageLoader.h>
#import <React/RCTDataRequestHandler.h>
#import <React/RCTFileRequestHandler.h>
#import <React/RCTGIFImageDecoder.h>
#import <React/RCTHTTPRequestHandler.h>
#import <React/RCTImageLoader.h>
#import <React/RCTNetworking.h>
// Fabric
#import <React/RCTFabricSurface.h>
#import <React/RCTSurfaceHostingProxyRootView.h>
// jsinspector-modern
#import <jsinspector-modern/InspectorFlags.h>
#import "RCTDependencyProvider.h"
void RCTAppSetupPrepareApp(UIApplication *application, BOOL turboModuleEnabled)
{
RCTEnableTurboModule(YES);
#if DEBUG
// Disable idle timer in dev builds to avoid putting application in background and complicating
// Metro reconnection logic. Users only need this when running the application using our CLI tooling.
application.idleTimerDisabled = YES;
#endif
}
UIView *
RCTAppSetupDefaultRootView(RCTBridge *bridge, NSString *moduleName, NSDictionary *initialProperties, BOOL fabricEnabled)
{
id<RCTSurfaceProtocol> surface = [[RCTFabricSurface alloc] initWithBridge:bridge
moduleName:moduleName
initialProperties:initialProperties];
UIView *rootView = [[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface];
[surface start];
return rootView;
}
NSArray<NSString *> *RCTAppSetupUnstableModulesRequiringMainQueueSetup(id<RCTDependencyProvider> dependencyProvider)
{
// For oss, insert core main queue setup modules here
return (dependencyProvider != nullptr) ? dependencyProvider.unstableModulesRequiringMainQueueSetup : @[];
}
id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(Class moduleClass, id<RCTDependencyProvider> dependencyProvider)
{
// private block used to filter out modules depending on protocol conformance
NSArray * (^extractModuleConformingToProtocol)(RCTModuleRegistry *, Protocol *) =
^NSArray *(RCTModuleRegistry *moduleRegistry, Protocol *protocol) {
NSArray<NSString *> *classNames = @[];
if (protocol == @protocol(RCTImageURLLoader)) {
classNames = (dependencyProvider != nullptr) ? dependencyProvider.imageURLLoaderClassNames : @[];
} else if (protocol == @protocol(RCTImageDataDecoder)) {
classNames = (dependencyProvider != nullptr) ? dependencyProvider.imageDataDecoderClassNames : @[];
} else if (protocol == @protocol(RCTURLRequestHandler)) {
classNames = (dependencyProvider != nullptr) ? dependencyProvider.URLRequestHandlerClassNames : @[];
}
NSMutableArray *modules = [NSMutableArray new];
for (NSString *className in classNames) {
const char *cModuleName = [className cStringUsingEncoding:NSUTF8StringEncoding];
id moduleFromLibrary = [moduleRegistry moduleForName:cModuleName];
if (![moduleFromLibrary conformsToProtocol:protocol]) {
continue;
}
[modules addObject:moduleFromLibrary];
}
return modules;
};
// Set up the default RCTImageLoader and RCTNetworking modules.
if (moduleClass == RCTImageLoader.class) {
return [[moduleClass alloc] initWithRedirectDelegate:nil
loadersProvider:^NSArray<id<RCTImageURLLoader>> *(RCTModuleRegistry *moduleRegistry) {
NSArray *imageURLLoaderModules =
extractModuleConformingToProtocol(moduleRegistry, @protocol(RCTImageURLLoader));
return [@[ [RCTBundleAssetImageLoader new] ] arrayByAddingObjectsFromArray:imageURLLoaderModules];
}
decodersProvider:^NSArray<id<RCTImageDataDecoder>> *(RCTModuleRegistry *moduleRegistry) {
NSArray *imageDataDecoder = extractModuleConformingToProtocol(moduleRegistry, @protocol(RCTImageDataDecoder));
return [@[ [RCTGIFImageDecoder new] ] arrayByAddingObjectsFromArray:imageDataDecoder];
}];
} else if (moduleClass == RCTNetworking.class) {
return [[moduleClass alloc]
initWithHandlersProvider:^NSArray<id<RCTURLRequestHandler>> *(RCTModuleRegistry *moduleRegistry) {
NSArray *URLRequestHandlerModules =
extractModuleConformingToProtocol(moduleRegistry, @protocol(RCTURLRequestHandler));
return [@[
[RCTHTTPRequestHandler new],
[RCTDataRequestHandler new],
[RCTFileRequestHandler new],
[moduleRegistry moduleForName:"BlobModule"],
] arrayByAddingObjectsFromArray:URLRequestHandlerModules];
}];
}
// No custom initializer here.
return [moduleClass new];
}
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutorFactory(
RCTBridge *bridge,
RCTTurboModuleManager *turboModuleManager,
const std::shared_ptr<facebook::react::RuntimeScheduler> &runtimeScheduler)
{
#ifndef RCT_REMOVE_LEGACY_ARCH
// Necessary to allow NativeModules to lookup TurboModules
[bridge setRCTTurboModuleRegistry:turboModuleManager];
#if RCT_DEV
/**
* Instantiating DevMenu has the side-effect of registering
* shortcuts for CMD + d, CMD + i, and CMD + n via RCTDevMenu.
* Therefore, when TurboModules are enabled, we must manually create this
* NativeModule.
*/
[turboModuleManager moduleForName:"RCTDevMenu"];
#endif // end RCT_DEV
auto runtimeInstallerLambda = [turboModuleManager, bridge, runtimeScheduler](facebook::jsi::Runtime &runtime) {
if (!bridge || !turboModuleManager) {
return;
}
if (runtimeScheduler) {
facebook::react::RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, runtimeScheduler);
}
[turboModuleManager installJSBindings:runtime];
};
#if USE_THIRD_PARTY_JSC != 1
return std::make_unique<facebook::react::HermesExecutorFactory>(
facebook::react::RCTJSIExecutorRuntimeInstaller(runtimeInstallerLambda));
#endif
#else
// This method should not be invoked in the New Arch. So when Legacy Arch is removed, we can
// safly return a nullptr.
return nullptr;
#endif
}
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupJsExecutorFactoryForOldArch(
RCTBridge *bridge,
const std::shared_ptr<facebook::react::RuntimeScheduler> &runtimeScheduler)
{
#ifndef RCT_REMOVE_LEGACY_ARCH
auto runtimeInstallerLambda = [bridge, runtimeScheduler](facebook::jsi::Runtime &runtime) {
if (!bridge) {
return;
}
if (runtimeScheduler) {
facebook::react::RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, runtimeScheduler);
}
};
#if USE_THIRD_PARTY_JSC != 1
return std::make_unique<facebook::react::HermesExecutorFactory>(
facebook::react::RCTJSIExecutorRuntimeInstaller(runtimeInstallerLambda));
#endif
#else
// This method should not be invoked in the New Arch. So when Legacy Arch is removed, we can
// safly return a nullptr.
return nullptr;
#endif
}

View File

@@ -0,0 +1,38 @@
/*
* 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 <React/RCTConvert.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
__attribute__((deprecated(
"RCTArchConfiguratorProtocol is deprecated and will be removed when we remove the legacy architecture.")));
@protocol RCTArchConfiguratorProtocol
/// This method controls whether the `turboModules` feature of the New Architecture is turned on or off.
///
/// @note: This is required to be rendering on Fabric (i.e. on the New Architecture).
/// @return: `true` if the Turbo Native Module are enabled. Otherwise, it returns `false`.
- (BOOL)turboModuleEnabled __attribute__((deprecated("This will be removed in a future version of React Native")));
/// This method controls whether the App will use the Fabric renderer of the New Architecture or not.
///
/// @return: `true` if the Fabric Renderer is enabled. Otherwise, it returns `false`.
- (BOOL)fabricEnabled __attribute__((deprecated("This will be removed in a future version of React Native")));
/// This method controls whether React Native's new initialization layer is enabled.
///
/// @return: `true` if the new initialization layer is enabled. Otherwise returns `false`.
- (BOOL)bridgelessEnabled __attribute__((deprecated("This will be removed in a future version of React Native")));
/// This method controls whether React Native uses new Architecture.
///
/// @return: `true` if the new architecture is enabled. Otherwise returns `false`.
- (BOOL)newArchEnabled __attribute__((deprecated("This will be removed in a future version of React Native")));
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,21 @@
/*
* 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 <UIKit/UIKit.h>
#import "RCTReactNativeFactory.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Default delegate for RCTReactNativeFactory.
* Contains default implementation of RCTReactNativeFactoryDelegate methods.
*/
@interface RCTDefaultReactNativeFactoryDelegate : UIResponder <RCTReactNativeFactoryDelegate>
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,146 @@
/*
* 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 "RCTDefaultReactNativeFactoryDelegate.h"
#import <ReactCommon/RCTHost.h>
#import "RCTAppSetupUtils.h"
#import "RCTDependencyProvider.h"
#if USE_THIRD_PARTY_JSC != 1
#import <React/RCTHermesInstanceFactory.h>
#endif
#import <react/nativemodule/defaults/DefaultTurboModules.h>
@implementation RCTDefaultReactNativeFactoryDelegate
@synthesize dependencyProvider;
- (NSURL *_Nullable)sourceURLForBridge:(nonnull RCTBridge *)bridge
{
[NSException raise:@"RCTBridgeDelegate::sourceURLForBridge not implemented"
format:@"Subclasses must implement a valid sourceURLForBridge method"];
return nil;
}
- (UIViewController *)createRootViewController
{
return [UIViewController new];
}
- (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions
{
return [[RCTBridge alloc] initWithDelegate:delegate launchOptions:launchOptions];
}
- (void)setRootView:(UIView *)rootView toRootViewController:(UIViewController *)rootViewController
{
rootViewController.view = rootView;
}
- (JSRuntimeFactoryRef)createJSRuntimeFactory
{
#if USE_THIRD_PARTY_JSC != 1
return jsrt_create_hermes_factory();
#endif
}
- (void)customizeRootView:(RCTRootView *)rootView
{
// Override point for customization after application launch.
}
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initProps:(NSDictionary *)initProps
{
UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, YES);
rootView.backgroundColor = [UIColor systemBackgroundColor];
return rootView;
}
- (RCTColorSpace)defaultColorSpace
{
return RCTColorSpaceSRGB;
}
- (NSURL *_Nullable)bundleURL
{
[NSException raise:@"RCTAppDelegate::bundleURL not implemented"
format:@"Subclasses must implement a valid getBundleURL method"];
return nullptr;
}
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
{
return (self.dependencyProvider != nullptr) ? self.dependencyProvider.thirdPartyFabricComponents : @{};
}
- (void)hostDidStart:(RCTHost *)host
{
}
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup
{
return (self.dependencyProvider != nullptr)
? RCTAppSetupUnstableModulesRequiringMainQueueSetup(self.dependencyProvider)
: @[];
}
- (nullable id<RCTModuleProvider>)getModuleProvider:(const char *)name
{
NSString *providerName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
return (self.dependencyProvider != nullptr) ? self.dependencyProvider.moduleProviders[providerName] : nullptr;
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
return facebook::react::DefaultTurboModules::getTurboModule(name, jsInvoker);
}
#pragma mark - RCTArchConfiguratorProtocol
- (BOOL)newArchEnabled
{
return YES;
}
- (BOOL)bridgelessEnabled
{
return YES;
}
- (BOOL)fabricEnabled
{
return YES;
}
- (BOOL)turboModuleEnabled
{
return YES;
}
- (Class)getModuleClassFromName:(const char *)name
{
return nullptr;
}
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
return nullptr;
}
- (void)loadSourceForBridge:(RCTBridge *)bridge
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback
{
[RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge] onProgress:onProgress onComplete:loadCallback];
}
@end

View File

@@ -0,0 +1,31 @@
/*
* 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 <Foundation/Foundation.h>
@protocol RCTComponentViewProtocol;
@protocol RCTModuleProvider;
NS_ASSUME_NONNULL_BEGIN
@protocol RCTDependencyProvider <NSObject>
- (NSArray<NSString *> *)imageURLLoaderClassNames;
- (NSArray<NSString *> *)imageDataDecoderClassNames;
- (NSArray<NSString *> *)URLRequestHandlerClassNames;
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup;
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
- (nonnull NSDictionary<NSString *, id<RCTModuleProvider>> *)moduleProviders;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,22 @@
/*
* 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.
*/
#pragma once
NS_ASSUME_NONNULL_BEGIN
// Forward declarations for umbrella headers.
// In implementations, import `<react/runtime/JSRuntimeFactoryCAPI.h>` to obtain the actual type.
typedef void *JSRuntimeFactoryRef;
@protocol RCTJSRuntimeConfiguratorProtocol
- (JSRuntimeFactoryRef)createJSRuntimeFactory;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,124 @@
/*
* 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 <React/RCTBridgeDelegate.h>
#import <React/RCTConvert.h>
#import <UIKit/UIKit.h>
#import "RCTArchConfiguratorProtocol.h"
#import "RCTDependencyProvider.h"
#import "RCTJSRuntimeConfiguratorProtocol.h"
#import "RCTRootViewFactory.h"
#import "RCTUIConfiguratorProtocol.h"
#if defined(__cplusplus) // Don't conform to protocols requiring C++ when it's not defined.
#import <React/RCTComponentViewFactory.h>
#import <ReactCommon/RCTHost.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#endif
@class RCTBridge;
@protocol RCTComponentViewProtocol;
@class RCTSurfacePresenterBridgeAdapter;
@class RCTDevMenuConfiguration;
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, RCTReleaseLevel) { Canary, Experimental, Stable };
@protocol RCTReactNativeFactoryDelegate <
RCTBridgeDelegate,
RCTUIConfiguratorProtocol,
#if defined(__cplusplus) // Don't conform to protocols requiring C++ when it's not defined.
RCTHostDelegate,
RCTTurboModuleManagerDelegate,
RCTComponentViewFactoryComponentProvider,
#endif
RCTJSRuntimeConfiguratorProtocol,
RCTArchConfiguratorProtocol>
/// Return the bundle URL for the main bundle.
- (NSURL *__nullable)bundleURL;
@property (nonatomic, strong) id<RCTDependencyProvider> dependencyProvider;
@optional
/**
* 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<RCTBridgeDelegate>)delegate
launchOptions:(NSDictionary *)launchOptions
__attribute__((deprecated(
"createBridgeWithDelegate:launchOptions: is deprecated and will be removed when removing the legacy architecture.")));
/**
* 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
__attribute__((deprecated(
"createRootViewWithBridge:moduleName:initProps is deprecated and will be removed when removing the legacy architecture.")));
/// This method returns a map of Component Descriptors and Components classes that needs to be registered in the
/// new renderer. The Component Descriptor is a string which represent the name used in JS to refer to the native
/// component. The default implementation returns an empty dictionary. Subclasses can override this method to register
/// the required components.
///
/// @return a dictionary that associate a component for the new renderer with his descriptor.
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
@end
@interface RCTReactNativeFactory : NSObject
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate;
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate releaseLevel:(RCTReleaseLevel)releaseLevel;
- (void)startReactNativeWithModuleName:(NSString *)moduleName inWindow:(UIWindow *_Nullable)window;
- (void)startReactNativeWithModuleName:(NSString *)moduleName
inWindow:(UIWindow *_Nullable)window
launchOptions:(NSDictionary *_Nullable)launchOptions;
- (void)startReactNativeWithModuleName:(NSString *)moduleName
inWindow:(UIWindow *_Nullable)window
initialProperties:(NSDictionary *_Nullable)initialProperties
launchOptions:(NSDictionary *_Nullable)launchOptions;
@property (nonatomic, nullable) RCTBridge *bridge
__attribute__((deprecated("The bridge is deprecated and will be removed when removing the legacy architecture.")));
@property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory;
@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter __attribute__((
deprecated("The bridgeAdapter is deprecated and will be removed when removing the legacy architecture.")));
;
@property (nonatomic, weak) id<RCTReactNativeFactoryDelegate> delegate;
@property (nonatomic, nullable) RCTDevMenuConfiguration *devMenuConfiguration;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,375 @@
/*
* 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 "RCTReactNativeFactory.h"
#import <React/RCTColorSpaceUtils.h>
#import <React/RCTDevMenu.h>
#import <React/RCTLog.h>
#import <React/RCTRootView.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <React/RCTUtils.h>
#import <ReactCommon/RCTHost.h>
#import <objc/runtime.h>
#import <react/featureflags/ReactNativeFeatureFlagsOverridesOSSCanary.h>
#import <react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h>
#import <react/featureflags/ReactNativeFeatureFlagsOverridesOSSStable.h>
#import <react/renderer/graphics/ColorComponents.h>
#import "RCTAppSetupUtils.h"
#if RN_DISABLE_OSS_PLUGIN_HEADER
#import <RCTTurboModulePlugin/RCTTurboModulePlugin.h>
#else
#import <React/CoreModulesPlugins.h>
#endif
#import <React/RCTComponentViewFactory.h>
#import <React/RCTComponentViewProtocol.h>
#import <react/nativemodule/defaults/DefaultTurboModules.h>
#import "RCTDependencyProvider.h"
using namespace facebook::react;
@interface RCTReactNativeFactory () <
RCTComponentViewFactoryComponentProvider,
RCTHostDelegate,
RCTJSRuntimeConfiguratorProtocol,
RCTTurboModuleManagerDelegate>
@end
@implementation RCTReactNativeFactory
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate
{
return [self initWithDelegate:delegate releaseLevel:Stable];
}
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate releaseLevel:(RCTReleaseLevel)releaseLevel
{
if (self = [super init]) {
self.delegate = delegate;
[self _setUpFeatureFlags:releaseLevel];
[RCTColorSpaceUtils applyDefaultColorSpace:[self defaultColorSpace]];
RCTEnableTurboModule(YES);
self.rootViewFactory = [self createRCTRootViewFactory];
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
}
return self;
}
- (void)startReactNativeWithModuleName:(NSString *)moduleName inWindow:(UIWindow *_Nullable)window
{
[self startReactNativeWithModuleName:moduleName inWindow:window initialProperties:nil launchOptions:nil];
}
- (void)startReactNativeWithModuleName:(NSString *)moduleName
inWindow:(UIWindow *_Nullable)window
launchOptions:(NSDictionary *_Nullable)launchOptions
{
[self startReactNativeWithModuleName:moduleName inWindow:window initialProperties:nil launchOptions:launchOptions];
}
- (void)startReactNativeWithModuleName:(NSString *)moduleName
inWindow:(UIWindow *_Nullable)window
initialProperties:(NSDictionary *_Nullable)initialProperties
launchOptions:(NSDictionary *_Nullable)launchOptions
{
UIView *rootView = [self.rootViewFactory viewWithModuleName:moduleName
initialProperties:initialProperties
launchOptions:launchOptions
devMenuConfiguration:self.devMenuConfiguration];
UIViewController *rootViewController = [_delegate createRootViewController];
[_delegate setRootView:rootView toRootViewController:rootViewController];
window.rootViewController = rootViewController;
[window makeKeyAndVisible];
}
#pragma mark - RCTUIConfiguratorProtocol
- (RCTColorSpace)defaultColorSpace
{
if ([_delegate respondsToSelector:@selector(defaultColorSpace)]) {
return [_delegate defaultColorSpace];
}
return RCTColorSpaceSRGB;
}
- (NSURL *_Nullable)bundleURL
{
if (![_delegate respondsToSelector:@selector(bundleURL)]) {
[NSException raise:@"RCTReactNativeFactoryDelegate::bundleURL not implemented"
format:@"Delegate must implement a valid getBundleURL method"];
}
return _delegate.bundleURL;
}
#pragma mark - RCTJSRuntimeConfiguratorProtocol
- (JSRuntimeFactoryRef)createJSRuntimeFactory
{
return [_delegate createJSRuntimeFactory];
}
#pragma mark - RCTArchConfiguratorProtocol
- (BOOL)newArchEnabled
{
return YES;
}
- (BOOL)fabricEnabled
{
return YES;
}
- (BOOL)turboModuleEnabled
{
return YES;
}
- (BOOL)bridgelessEnabled
{
return YES;
}
#pragma mark - RCTTurboModuleManagerDelegate
- (Class)getModuleClassFromName:(const char *)name
{
#if RN_DISABLE_OSS_PLUGIN_HEADER
return RCTTurboModulePluginClassProvider(name);
#else
if ([_delegate respondsToSelector:@selector(getModuleClassFromName:)]) {
Class moduleClass = [_delegate getModuleClassFromName:name];
if (moduleClass != nil) {
return moduleClass;
}
}
return RCTCoreModulesClassProvider(name);
#endif
}
- (nullable id<RCTModuleProvider>)getModuleProvider:(const char *)name
{
if ([_delegate respondsToSelector:@selector(getModuleProvider:)]) {
return [_delegate getModuleProvider:name];
}
return nil;
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
if ([_delegate respondsToSelector:@selector(getTurboModule:jsInvoker:)]) {
return [_delegate getTurboModule:name jsInvoker:jsInvoker];
}
return facebook::react::DefaultTurboModules::getTurboModule(name, jsInvoker);
}
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
#if USE_OSS_CODEGEN
if (self.delegate.dependencyProvider == nil) {
[NSException raise:@"ReactNativeFactoryDelegate dependencyProvider is nil"
format:@"Delegate must provide a valid dependencyProvider"];
}
#endif
if ([_delegate respondsToSelector:@selector(getModuleInstanceFromClass:)]) {
id<RCTTurboModule> moduleInstance = [_delegate getModuleInstanceFromClass:moduleClass];
if (moduleInstance != nil) {
return moduleInstance;
}
}
return RCTAppSetupDefaultModuleFromClass(moduleClass, self.delegate.dependencyProvider);
}
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
if ([_delegate respondsToSelector:@selector(extraModulesForBridge:)]) {
return [_delegate extraModulesForBridge:bridge];
}
return @[];
}
#pragma mark - RCTComponentViewFactoryComponentProvider
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
{
if ([_delegate respondsToSelector:@selector(thirdPartyFabricComponents)]) {
return _delegate.thirdPartyFabricComponents;
}
return self.delegate.dependencyProvider ? self.delegate.dependencyProvider.thirdPartyFabricComponents : @{};
}
#pragma mark - RCTHostDelegate
- (void)hostDidStart:(RCTHost *)host
{
if ([_delegate respondsToSelector:@selector(hostDidStart:)]) {
[_delegate hostDidStart:host];
}
}
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup
{
#if RN_DISABLE_OSS_PLUGIN_HEADER
return RCTTurboModulePluginUnstableModulesRequiringMainQueueSetup();
#else
return self.delegate.dependencyProvider
? RCTAppSetupUnstableModulesRequiringMainQueueSetup(self.delegate.dependencyProvider)
: @[];
#endif
}
- (RCTRootViewFactory *)createRCTRootViewFactory
{
__weak __typeof(self) weakSelf = self;
RCTBundleURLBlock bundleUrlBlock = ^{
auto *strongSelf = weakSelf;
return strongSelf.bundleURL;
};
RCTRootViewFactoryConfiguration *configuration =
[[RCTRootViewFactoryConfiguration alloc] initWithBundleURLBlock:bundleUrlBlock
newArchEnabled:YES
turboModuleEnabled:YES
bridgelessEnabled:YES];
configuration.createRootViewWithBridge = ^UIView *(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps) {
return [weakSelf.delegate createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps];
};
configuration.createBridgeWithDelegate = ^RCTBridge *(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions) {
return [weakSelf.delegate createBridgeWithDelegate:delegate launchOptions:launchOptions];
};
configuration.customizeRootView = ^(UIView *_Nonnull rootView) {
[weakSelf.delegate customizeRootView:(RCTRootView *)rootView];
};
configuration.sourceURLForBridge = ^NSURL *_Nullable(RCTBridge *_Nonnull bridge)
{
#ifndef RCT_REMOVE_LEGACY_ARCH
return [weakSelf.delegate sourceURLForBridge:bridge];
#else
// When the Legacy Arch is removed, the Delegate does not have a sourceURLForBridge method
return [weakSelf.delegate bundleURL];
#endif
};
if ([self.delegate respondsToSelector:@selector(extraModulesForBridge:)]) {
configuration.extraModulesForBridge = ^NSArray<id<RCTBridgeModule>> *_Nonnull(RCTBridge *_Nonnull bridge)
{
return [weakSelf.delegate extraModulesForBridge:bridge];
};
}
if ([self.delegate respondsToSelector:@selector(extraLazyModuleClassesForBridge:)]) {
configuration.extraLazyModuleClassesForBridge =
^NSDictionary<NSString *, Class> *_Nonnull(RCTBridge *_Nonnull bridge)
{
#ifndef RCT_REMOVE_LEGACY_ARCH
return [weakSelf.delegate extraLazyModuleClassesForBridge:bridge];
#else
// When the Legacy Arch is removed, the Delegate does not have a extraLazyModuleClassesForBridge method
return @{};
#endif
};
}
if ([self.delegate respondsToSelector:@selector(bridge:didNotFindModule:)]) {
configuration.bridgeDidNotFindModule = ^BOOL(RCTBridge *_Nonnull bridge, NSString *_Nonnull moduleName) {
#ifndef RCT_REMOVE_LEGACY_ARCH
return [weakSelf.delegate bridge:bridge didNotFindModule:moduleName];
#else
// When the Legacy Arch is removed, the Delegate does not have a bridge:didNotFindModule method
// We return NO, because if we have invoked this method is unlikely that the module will be actually registered
return NO;
#endif
};
}
if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:onProgress:onComplete:)]) {
configuration.loadSourceForBridgeWithProgress =
^(RCTBridge *_Nonnull bridge,
RCTSourceLoadProgressBlock _Nonnull onProgress,
RCTSourceLoadBlock _Nonnull loadCallback) {
#ifndef RCT_REMOVE_LEGACY_ARCH
[weakSelf.delegate loadSourceForBridge:bridge onProgress:onProgress onComplete:loadCallback];
#else
// When the Legacy Arch is removed, the Delegate does not have a
// loadSourceForBridge:onProgress:onComplete: method
// We then call the loadBundleAtURL:onProgress:onComplete: instead
[weakSelf.delegate loadBundleAtURL:self.bundleURL onProgress:onProgress onComplete:loadCallback];
#endif
};
}
if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:withBlock:)]) {
configuration.loadSourceForBridge = ^(RCTBridge *_Nonnull bridge, RCTSourceLoadBlock _Nonnull loadCallback) {
#ifndef RCT_REMOVE_LEGACY_ARCH
[weakSelf.delegate loadSourceForBridge:bridge withBlock:loadCallback];
#else
// When the Legacy Arch is removed, the Delegate does not have a
// loadSourceForBridge:withBlock: method
// We then call the loadBundleAtURL:onProgress:onComplete: instead
[weakSelf.delegate loadBundleAtURL:self.bundleURL
onProgress:^(RCTLoadingProgress *progressData) {
}
onComplete:loadCallback];
#endif
};
}
configuration.jsRuntimeConfiguratorDelegate = self;
return [[RCTRootViewFactory alloc] initWithTurboModuleDelegate:self hostDelegate:self configuration:configuration];
}
#pragma mark - Feature Flags
- (void)_setUpFeatureFlags:(RCTReleaseLevel)releaseLevel
{
static BOOL initialized = NO;
static RCTReleaseLevel chosenReleaseLevel;
NSLog(@"_setUpFeatureFlags called with release level %li", releaseLevel);
if (!initialized) {
chosenReleaseLevel = releaseLevel;
initialized = YES;
} else if (chosenReleaseLevel != releaseLevel) {
[NSException
raise:@"RCTReactNativeFactory::_setUpFeatureFlags releaseLevel mismatch between React Native instances"
format:@"The releaseLevel (%li) of the new instance does not match the previous instance's releaseLevel (%li)",
releaseLevel,
chosenReleaseLevel];
}
static dispatch_once_t setupFeatureFlagsToken;
dispatch_once(&setupFeatureFlagsToken, ^{
switch (releaseLevel) {
case Stable:
ReactNativeFeatureFlags::override(std::make_unique<ReactNativeFeatureFlagsOverridesOSSStable>());
break;
case Canary:
ReactNativeFeatureFlags::override(std::make_unique<ReactNativeFeatureFlagsOverridesOSSCanary>());
break;
case Experimental:
ReactNativeFeatureFlags::override(std::make_unique<ReactNativeFeatureFlagsOverridesOSSExperimental>());
break;
}
});
}
@end

View File

@@ -0,0 +1,241 @@
/*
* 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 <React/RCTBridge.h>
#import <React/RCTRootView.h>
#import <React/RCTUtils.h>
#import "RCTJSRuntimeConfiguratorProtocol.h"
@protocol RCTCxxBridgeDelegate;
@protocol RCTComponentViewFactoryComponentProvider;
@protocol RCTTurboModuleManagerDelegate;
@protocol RCTHostDelegate;
@class RCTBridge;
@class RCTHost;
@class RCTRootView;
@class RCTSurfacePresenterBridgeAdapter;
@class RCTDevMenuConfiguration;
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Blocks' definitions
typedef UIView *_Nonnull (
^RCTCreateRootViewWithBridgeBlock)(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps);
typedef RCTBridge *_Nonnull (
^RCTCreateBridgeWithDelegateBlock)(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions);
typedef void (^RCTCustomizeRootViewBlock)(UIView *rootView);
typedef NSURL *_Nullable (^RCTSourceURLForBridgeBlock)(RCTBridge *bridge);
typedef NSURL *_Nullable (^RCTBundleURLBlock)(void);
typedef NSArray<id<RCTBridgeModule>> *_Nonnull (^RCTExtraModulesForBridgeBlock)(RCTBridge *bridge);
typedef NSDictionary<NSString *, Class> *_Nonnull (^RCTExtraLazyModuleClassesForBridge)(RCTBridge *bridge);
typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *moduleName);
typedef void (^RCTLoadSourceForBridgeWithProgressBlock)(
RCTBridge *bridge,
RCTSourceLoadProgressBlock onProgress,
RCTSourceLoadBlock loadCallback);
typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBlock loadCallback);
#pragma mark - RCTRootViewFactory Configuration
@interface RCTRootViewFactoryConfiguration : NSObject
/// This property controls whether the App will use the Fabric renderer of the New Architecture or not.
@property (nonatomic, assign, readonly) BOOL fabricEnabled;
/// This property controls whether React Native's new initialization layer is enabled.
@property (nonatomic, assign, readonly) BOOL bridgelessEnabled;
/// This method controls whether the `turboModules` feature of the New Architecture is turned on or off
@property (nonatomic, assign, readonly) BOOL turboModuleEnabled;
/// Return the bundle URL for the main bundle.
@property (nonatomic, nonnull) RCTBundleURLBlock bundleURLBlock;
/**
* Use this method to initialize a new instance of `RCTRootViewFactoryConfiguration` by passing a `bundleURL`
*
* Which is 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`.
*
*/
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock
newArchEnabled:(BOOL)newArchEnabled
turboModuleEnabled:(BOOL)turboModuleEnabled
bridgelessEnabled:(BOOL)bridgelessEnabled __deprecated;
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
newArchEnabled:(BOOL)newArchEnabled
turboModuleEnabled:(BOOL)turboModuleEnabled
bridgelessEnabled:(BOOL)bridgelessEnabled __deprecated;
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock
newArchEnabled:(BOOL)newArchEnabled NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithBundleURL:(NSURL *)bundleURL newArchEnabled:(BOOL)newArchEnabled;
/**
* Block that allows to override logic of creating root view instance.
* 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 `RCTCreateBridgeWithDelegateBlock` (or the default
* implementation) and the `moduleName` variable comes from `viewWithModuleName:initialProperties:launchOptions` of
* `RCTRootViewFactory`.
*
* @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.
*/
@property (nonatomic, nullable) RCTCreateRootViewWithBridgeBlock createRootViewWithBridge;
/**
* Block that allows to override default behavior of creating bridge.
* It should return `RCTBridge` using a delegate and some launch options.
*
* By default, it is invoked passing `self` as a delegate.
*
* @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.
*/
@property (nonatomic, nullable) RCTCreateBridgeWithDelegateBlock createBridgeWithDelegate;
/**
* Block that allows to customize the rootView that is passed to React Native.
*
* @parameter: rootView - The root view to customize.
*/
@property (nonatomic, nullable) RCTCustomizeRootViewBlock customizeRootView;
@property (nonatomic, weak, nullable) id<RCTJSRuntimeConfiguratorProtocol> jsRuntimeConfiguratorDelegate;
#pragma mark - RCTBridgeDelegate blocks
/**
* 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;
/**
* The bridge will automatically attempt to load the JS source code from the
* location specified by the `sourceURLForBridge:` method, however, if you want
* to handle loading the JS yourself, you can do so by setting this property.
*/
@property (nonatomic, nullable) RCTLoadSourceForBridgeWithProgressBlock loadSourceForBridgeWithProgress;
/**
* Similar to loadSourceForBridgeWithProgress but without progress
* reporting.
*/
@property (nonatomic, nullable) RCTLoadSourceForBridgeBlock loadSourceForBridge;
@end
#pragma mark - RCTRootViewFactory
/**
* The RCTRootViewFactory is an utility class that encapsulates the logic of creating a new RCTRootView based on the
* current state of the environment. It allows you to initialize your app root view for old architecture, new
* architecture and bridgless mode.
*
* This class is used to initalize rootView in RCTAppDelegate, but you can also use it separately.
*
* Create a new instance of this class (make sure to retain it) and call the
* `viewWithModuleName:initialProperties:launchOptions` method to create new RCTRootView.
*/
@interface RCTRootViewFactory : NSObject
@property (nonatomic, strong, nullable) RCTBridge *bridge;
@property (nonatomic, strong, nullable) RCTHost *reactHost;
@property (nonatomic, strong, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration
andTurboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate> _Nullable)turboModuleManagerDelegate;
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration;
- (instancetype)initWithTurboModuleDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
hostDelegate:(id<RCTHostDelegate>)hostdelegate
configuration:(RCTRootViewFactoryConfiguration *)configuration;
/**
* This method can be used to create new RCTRootViews on demand.
*
* @parameter: moduleName - the name of the app, used by Metro to resolve the module.
* @parameter: initialProperties - a set of initial properties.
* @parameter: launchOptions - a dictionary with a set of options.
* @parameter: devMenuConfiguration - a configuration for enabling/disabling dev menu.
*/
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
initialProperties:(NSDictionary *__nullable)initialProperties
launchOptions:(NSDictionary *__nullable)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *__nullable)devMenuConfiguration;
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
initialProperties:(NSDictionary *__nullable)initialProperties
launchOptions:(NSDictionary *__nullable)launchOptions;
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
initialProperties:(NSDictionary *__nullable)initialProperties;
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName;
#pragma mark - RCTRootViewFactory Helpers
/**
* Initialize React Host/Bridge without creating a view.
*
* Use it to speed up later viewWithModuleName: calls.
*
* @parameter: launchOptions - a dictionary with a set of options.
* @parameter: devMenuConfiguration - a configuration for enabling/disabling dev menu.
*/
- (void)initializeReactHostWithLaunchOptions:(NSDictionary *__nullable)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration;
- (RCTHost *)createReactHost:(NSDictionary *__nullable)launchOptions;
- (RCTHost *)createReactHost:(NSDictionary *__nullable)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *__nullable)devMenuConfiguration;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,348 @@
/*
* 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 "RCTRootViewFactory.h"
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTDevMenu.h>
#import <React/RCTLog.h>
#import <React/RCTRootView.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <React/RCTUtils.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import "RCTAppDelegate.h"
#import "RCTAppSetupUtils.h"
#if RN_DISABLE_OSS_PLUGIN_HEADER
#import <RCTTurboModulePlugin/RCTTurboModulePlugin.h>
#else
#import <React/CoreModulesPlugins.h>
#endif
#import <React/RCTBundleURLProvider.h>
#import <React/RCTComponentViewFactory.h>
#import <React/RCTComponentViewProtocol.h>
#import <React/RCTFabricSurface.h>
#import <React/RCTSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <ReactCommon/RCTHost+Internal.h>
#import <ReactCommon/RCTHost.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
#import <react/runtime/JSRuntimeFactory.h>
#import <react/runtime/JSRuntimeFactoryCAPI.h>
@implementation RCTRootViewFactoryConfiguration
- (instancetype)initWithBundleURL:(NSURL *)bundleURL newArchEnabled:(BOOL)newArchEnabled
{
return [self initWithBundleURL:bundleURL];
}
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock newArchEnabled:(BOOL)newArchEnabled
{
return [self initWithBundleURLBlock:bundleURLBlock];
}
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
newArchEnabled:(BOOL)newArchEnabled
turboModuleEnabled:(BOOL)turboModuleEnabled
bridgelessEnabled:(BOOL)bridgelessEnabled
{
return [self initWithBundleURLBlock:^{
return bundleURL;
}];
}
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock
newArchEnabled:(BOOL)newArchEnabled
turboModuleEnabled:(BOOL)turboModuleEnabled
bridgelessEnabled:(BOOL)bridgelessEnabled
{
if (self = [super init]) {
_bundleURLBlock = bundleURLBlock;
_fabricEnabled = YES;
_turboModuleEnabled = YES;
_bridgelessEnabled = YES;
}
return self;
}
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock
{
if (self = [super init]) {
_bundleURLBlock = bundleURLBlock;
_fabricEnabled = YES;
_turboModuleEnabled = YES;
_bridgelessEnabled = YES;
}
return self;
}
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
{
return [self initWithBundleURLBlock:^{
return bundleURL;
}];
}
@end
@interface RCTRootViewFactory () <RCTCxxBridgeDelegate> {
std::shared_ptr<const facebook::react::ContextContainer> _contextContainer;
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
}
@end
@implementation RCTRootViewFactory {
__weak id<RCTTurboModuleManagerDelegate> _turboModuleManagerDelegate;
__weak id<RCTHostDelegate> _hostDelegate;
RCTRootViewFactoryConfiguration *_configuration;
}
- (instancetype)initWithTurboModuleDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
hostDelegate:(id<RCTHostDelegate>)hostdelegate
configuration:(RCTRootViewFactoryConfiguration *)configuration
{
if (self = [super init]) {
_configuration = configuration;
_hostDelegate = hostdelegate;
_contextContainer = std::make_shared<const facebook::react::ContextContainer>();
_turboModuleManagerDelegate = turboModuleManagerDelegate;
}
return self;
}
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration
andTurboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
{
id<RCTHostDelegate> hostDelegate = [turboModuleManagerDelegate conformsToProtocol:@protocol(RCTHostDelegate)]
? (id<RCTHostDelegate>)turboModuleManagerDelegate
: nil;
return [self initWithTurboModuleDelegate:turboModuleManagerDelegate
hostDelegate:hostDelegate
configuration:configuration];
}
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration
{
return [self initWithConfiguration:configuration andTurboModuleManagerDelegate:nil];
}
- (UIView *)viewWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary *)initialProperties
{
return [self viewWithModuleName:moduleName
initialProperties:initialProperties
launchOptions:nil
devMenuConfiguration:[RCTDevMenuConfiguration defaultConfiguration]];
}
- (UIView *)viewWithModuleName:(NSString *)moduleName
{
return [self viewWithModuleName:moduleName
initialProperties:nil
launchOptions:nil
devMenuConfiguration:[RCTDevMenuConfiguration defaultConfiguration]];
}
- (void)initializeReactHostWithLaunchOptions:(NSDictionary *)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
{
// Enable TurboModule interop by default in Bridgeless mode
RCTEnableTurboModuleInterop(YES);
RCTEnableTurboModuleInteropBridgeProxy(YES);
[self createReactHostIfNeeded:launchOptions devMenuConfiguration:devMenuConfiguration];
return;
}
- (UIView *)viewWithModuleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
launchOptions:(NSDictionary *)launchOptions
{
return [self viewWithModuleName:moduleName
initialProperties:initialProperties
launchOptions:launchOptions
devMenuConfiguration:[RCTDevMenuConfiguration defaultConfiguration]];
}
- (UIView *)viewWithModuleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initProps
launchOptions:(NSDictionary *)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
{
[self initializeReactHostWithLaunchOptions:launchOptions devMenuConfiguration:devMenuConfiguration];
RCTFabricSurface *surface = [self.reactHost createSurfaceWithModuleName:moduleName
initialProperties:initProps ? initProps : @{}];
RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView =
[[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface];
surfaceHostingProxyRootView.backgroundColor = [UIColor systemBackgroundColor];
if (_configuration.customizeRootView != nil) {
_configuration.customizeRootView(surfaceHostingProxyRootView);
}
return surfaceHostingProxyRootView;
}
- (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions
{
return [[RCTBridge alloc] initWithDelegate:delegate launchOptions:launchOptions];
}
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initProps:(NSDictionary *)initProps
{
UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, YES);
rootView.backgroundColor = [UIColor systemBackgroundColor];
return rootView;
}
#pragma mark - RCTCxxBridgeDelegate
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
std::shared_ptr<facebook::react::CallInvoker> callInvoker =
std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(_runtimeScheduler);
RCTTurboModuleManager *turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:_turboModuleManagerDelegate
jsInvoker:callInvoker];
_contextContainer->erase(facebook::react::RuntimeSchedulerKey);
_contextContainer->insert(facebook::react::RuntimeSchedulerKey, _runtimeScheduler);
return RCTAppSetupDefaultJsExecutorFactory(bridge, turboModuleManager, _runtimeScheduler);
}
- (void)createBridgeIfNeeded:(NSDictionary *)launchOptions
{
if (self.bridge != nil) {
return;
}
if (self->_configuration.createBridgeWithDelegate != nil) {
self.bridge = self->_configuration.createBridgeWithDelegate(self, launchOptions);
} else {
self.bridge = [self createBridgeWithDelegate:self launchOptions:launchOptions];
}
}
- (void)createBridgeAdapterIfNeeded
{
if (self.bridgeAdapter != nullptr) {
return;
}
self.bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:self.bridge
contextContainer:_contextContainer];
self.bridge.surfacePresenter = self.bridgeAdapter.surfacePresenter;
}
#pragma mark - New Arch Utilities
- (void)createReactHostIfNeeded:(NSDictionary *)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
{
if (self.reactHost) {
return;
}
self.reactHost = [self createReactHost:launchOptions devMenuConfiguration:devMenuConfiguration];
}
- (RCTHost *)createReactHost:(NSDictionary *)launchOptions
{
return [self createReactHost:launchOptions devMenuConfiguration:[RCTDevMenuConfiguration defaultConfiguration]];
}
- (RCTHost *)createReactHost:(NSDictionary *)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
{
__weak __typeof(self) weakSelf = self;
RCTHost *reactHost =
[[RCTHost alloc] initWithBundleURLProvider:self->_configuration.bundleURLBlock
hostDelegate:_hostDelegate
turboModuleManagerDelegate:_turboModuleManagerDelegate
jsEngineProvider:^std::shared_ptr<facebook::react::JSRuntimeFactory>() {
return [weakSelf createJSRuntimeFactory];
}
launchOptions:launchOptions
devMenuConfiguration:devMenuConfiguration];
[reactHost setBundleURLProvider:^NSURL *() {
return [weakSelf bundleURL];
}];
[reactHost start];
return reactHost;
}
- (std::shared_ptr<facebook::react::JSRuntimeFactory>)createJSRuntimeFactory
{
if (_configuration.jsRuntimeConfiguratorDelegate == nil) {
[NSException raise:@"RCTReactNativeFactoryDelegate::createJSRuntimeFactory not implemented"
format:@"Delegate must implement a valid createJSRuntimeFactory method"];
return nullptr;
}
auto jsRuntimeFactory = [_configuration.jsRuntimeConfiguratorDelegate createJSRuntimeFactory];
return std::shared_ptr<facebook::react::JSRuntimeFactory>(
reinterpret_cast<facebook::react::JSRuntimeFactory *>(jsRuntimeFactory), &js_runtime_factory_destroy);
}
- (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;
}
- (void)loadSourceForBridge:(RCTBridge *)bridge withBlock:(RCTSourceLoadBlock)loadCallback
{
if (_configuration.loadSourceForBridge != nil) {
_configuration.loadSourceForBridge(bridge, loadCallback);
}
}
- (void)loadSourceForBridge:(RCTBridge *)bridge
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback
{
if (_configuration.loadSourceForBridgeWithProgress != nil) {
_configuration.loadSourceForBridgeWithProgress(bridge, onProgress, loadCallback);
}
}
- (NSURL *)bundleURL
{
return self->_configuration.bundleURLBlock();
}
@end

View File

@@ -0,0 +1,60 @@
/*
* 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 <React/RCTConvert.h>
#import <UIKit/UIKit.h>
@class RCTRootView;
NS_ASSUME_NONNULL_BEGIN
@protocol RCTUIConfiguratorProtocol
/**
* The default `RCTColorSpace` for the app. It defaults to `RCTColorSpaceSRGB`.
*/
- (RCTColorSpace)defaultColorSpace;
/**
* This method can be used to customize the rootView that is passed to React Native.
* A typical example is to override this method in the AppDelegate to change the background color.
* To achieve this, add in your `AppDelegate.mm`:
* ```
* - (void)customizeRootView:(RCTRootView *)rootView
* {
* rootView.backgroundColor = [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) {
* if ([traitCollection userInterfaceStyle] == UIUserInterfaceStyleDark) {
* return [UIColor blackColor];
* } else {
* return [UIColor whiteColor];
* }
* }];
* }
* ```
*
* @parameter: rootView - The root view to customize.
*/
- (void)customizeRootView:(RCTRootView *)rootView;
/**
* 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;
/**
* It assigns the rootView to the rootViewController
* By default, it assigns the rootView to the view property of the rootViewController
* If you are not using a simple UIViewController, then there could be other methods to use to setup the rootView.
* For example: UISplitViewController requires `setViewController(_:for:)`
*/
- (void)setRootView:(UIView *)rootView toRootViewController:(UIViewController *)rootViewController;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,88 @@
# 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.
require "json"
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
version = package['version']
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
is_new_arch_enabled = ENV["RCT_NEW_ARCH_ENABLED"] != "0"
new_arch_enabled_flag = (is_new_arch_enabled ? " -DRCT_NEW_ARCH_ENABLED=1" : "")
other_cflags = "$(inherited) " + new_arch_enabled_flag + js_engine_flags()
header_search_paths = [
"$(PODS_TARGET_SRCROOT)/../../ReactCommon",
"$(PODS_ROOT)/Headers/Private/React-Core",
"${PODS_ROOT}/Headers/Public/FlipperKit",
"$(PODS_ROOT)/Headers/Public/ReactCommon",
"$(PODS_ROOT)/Headers/Public/React-RCTFabric",
"$(PODS_ROOT)/Headers/Private/Yoga",
].concat(use_hermes() ? [
"$(PODS_ROOT)/Headers/Public/React-hermes",
"$(PODS_ROOT)/Headers/Public/hermes-engine"
] : [])
Pod::Spec.new do |s|
s.name = "React-RCTAppDelegate"
s.version = version
s.summary = "An utility library to simplify common operations for the New Architecture"
s.homepage = "https://reactnative.dev/"
s.documentation_url = "https://reactnative.dev/"
s.license = package["license"]
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.source_files = podspec_sources("**/*.{c,h,m,mm,S,cpp}", "**/*.h")
# This guard prevent to install the dependencies when we run `pod install` in the old architecture.
s.compiler_flags = other_cflags
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => header_search_paths,
"OTHER_CPLUSPLUSFLAGS" => other_cflags,
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"DEFINES_MODULE" => "YES"
}
s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\" \"$(PODS_ROOT)/Headers/Private/Yoga\""}
s.dependency "React-Core"
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "React-RCTNetwork"
s.dependency "React-RCTImage"
s.dependency "React-CoreModules"
s.dependency "React-RCTFBReactNativeSpec"
s.dependency "React-defaultsnativemodule"
if use_hermes()
s.dependency 'React-hermes'
end
add_dependency(s, "React-runtimeexecutor", :additional_framework_paths => ["platform/ios"])
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple")
add_dependency(s, "React-runtimescheduler")
add_dependency(s, "React-RCTFabric", :framework_name => "RCTFabric")
add_dependency(s, "React-RuntimeCore")
add_dependency(s, "React-RuntimeApple")
add_dependency(s, "React-Fabric", :additional_framework_paths => ["react/renderer/components/view/platform/cxx"])
add_dependency(s, "React-graphics", :additional_framework_paths => ["react/renderer/graphics/platform/ios"])
add_dependency(s, "React-utils")
add_dependency(s, "React-debug")
add_dependency(s, "React-rendererdebug")
add_dependency(s, "React-featureflags")
add_dependency(s, "React-jsitooling", :framework_name => "JSITooling")
add_dependency(s, "React-RCTRuntime", :framework_name => "RCTRuntime")
depend_on_js_engine(s)
add_rn_third_party_dependencies(s)
add_rncore_dependency(s)
end