From 7aded8415d0fa905515cf2efdcec5e9909d6c9ab Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Mon, 18 May 2026 03:15:33 -0700 Subject: [PATCH] Compile out RCTCxxBridge when legacy arch is disabled (#56837) Summary: Fully remove the symbols for RCTCxxBridge when remove-legacy-arch is enabled. Changelog: [iOS][Breaking] Removing further legacy arch symbols such as RCTCxxBridge Reviewed By: christophpurrer Differential Revision: D105167968 --- .../Libraries/AppDelegate/RCTAppDelegate.h | 9 +-- .../Libraries/AppDelegate/RCTAppDelegate.mm | 2 + .../AppDelegate/RCTReactNativeFactory.h | 7 ++- .../AppDelegate/RCTRootViewFactory.h | 5 +- .../AppDelegate/RCTRootViewFactory.mm | 63 +------------------ .../React/Base/RCTBridge+Private.h | 4 +- .../react-native/React/Base/RCTBridgeProxy.mm | 4 ++ .../React/CxxBridge/RCTCxxBridge.mm | 3 - .../Fabric/RCTSurfacePresenterBridgeAdapter.h | 2 + .../RCTSurfacePresenterBridgeAdapter.mm | 3 +- .../ios/ReactCommon/RCTTurboModuleManager.mm | 15 ++--- 11 files changed, 36 insertions(+), 81 deletions(-) diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h index 66d64d22044d..00f5e97ccdad 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h @@ -66,8 +66,13 @@ __attribute__((deprecated( /// The window object, used to render the UViewControllers @property (nonatomic, strong, nonnull) UIWindow *window; +#if !defined(RCT_REMOVE_LEGACY_ARCH) @property (nonatomic, nullable) RCTBridge *bridge __attribute__((deprecated("The bridge is deprecated and will be removed when removing the legacy architecture."))); +@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter __attribute__(( + deprecated("The bridge adapter is deprecated and will be removed when removing the legacy architecture."))); +#endif + @property (nonatomic, strong, nullable) NSString *moduleName; @property (nonatomic, strong, nullable) NSDictionary *initialProps; @property (nonatomic, strong) RCTReactNativeFactory *reactNativeFactory; @@ -75,10 +80,6 @@ __attribute__((deprecated( /// 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 diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm index 8abc2fc431bf..6bda970079cc 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm @@ -67,6 +67,7 @@ - (RCTRootViewFactory *)rootViewFactory return self.reactNativeFactory.rootViewFactory; } +#if !defined(RCT_REMOVE_LEGACY_ARCH) - (RCTBridge *)bridge { return self.rootViewFactory.bridge; @@ -86,5 +87,6 @@ - (void)setBridgeAdapter:(RCTSurfacePresenterBridgeAdapter *)bridgeAdapter { self.reactNativeFactory.rootViewFactory.bridgeAdapter = bridgeAdapter; } +#endif @end diff --git a/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.h b/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.h index 1671d7080907..07afa92fd50a 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.h +++ b/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.h @@ -108,13 +108,14 @@ typedef NS_ENUM(NSInteger, RCTReleaseLevel) { Canary, Experimental, Stable }; initialProperties:(NSDictionary *_Nullable)initialProperties launchOptions:(NSDictionary *_Nullable)launchOptions; +#if !defined(RCT_REMOVE_LEGACY_ARCH) @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."))); -; +#endif + +@property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory; @property (nonatomic, weak) id delegate; diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h index de533570ea60..ddd3c09ebfbf 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h @@ -184,9 +184,12 @@ typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBloc */ @interface RCTRootViewFactory : NSObject +#if !defined(RCT_REMOVE_LEGACY_ARCH) @property (nonatomic, strong, nullable) RCTBridge *bridge; -@property (nonatomic, strong, nullable) RCTHost *reactHost; @property (nonatomic, strong, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter; +#endif + +@property (nonatomic, strong, nullable) RCTHost *reactHost; - (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration andTurboModuleManagerDelegate:(id _Nullable)turboModuleManagerDelegate; diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm index 4eaecb0b46ef..4473d6f503d4 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm @@ -6,11 +6,9 @@ */ #import "RCTRootViewFactory.h" -#import #import #import #import -#import #import #import #import "RCTAppDelegate.h" @@ -90,7 +88,7 @@ - (instancetype)initWithBundleURL:(NSURL *)bundleURL @end -@interface RCTRootViewFactory () { +@interface RCTRootViewFactory () { std::shared_ptr _contextContainer; std::shared_ptr _runtimeScheduler; } @@ -201,63 +199,6 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName return surfaceHostingProxyRootView; } -- (RCTBridge *)createBridgeWithDelegate:(id)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); -#if !TARGET_OS_TV - rootView.backgroundColor = [UIColor systemBackgroundColor]; -#else - rootView.backgroundColor = [UIColor blackColor]; -#endif - return rootView; -} - -#pragma mark - RCTCxxBridgeDelegate -- (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge -{ - _runtimeScheduler = std::make_shared(RCTRuntimeExecutorFromBridge(bridge)); - - std::shared_ptr callInvoker = - std::make_shared(_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 @@ -324,6 +265,7 @@ - (RCTHost *)createReactHost:(NSDictionary *)launchOptions return nil; } +#ifndef RCT_REMOVE_LEGACY_ARCH - (NSDictionary *)extraLazyModuleClassesForBridge:(RCTBridge *)bridge { if (_configuration.extraLazyModuleClassesForBridge != nil) { @@ -363,6 +305,7 @@ - (void)loadSourceForBridge:(RCTBridge *)bridge _configuration.loadSourceForBridgeWithProgress(bridge, onProgress, loadCallback); } } +#endif - (NSURL *)bundleURL { diff --git a/packages/react-native/React/Base/RCTBridge+Private.h b/packages/react-native/React/Base/RCTBridge+Private.h index 3a69f317ebf3..6c2c82832850 100644 --- a/packages/react-native/React/Base/RCTBridge+Private.h +++ b/packages/react-native/React/Base/RCTBridge+Private.h @@ -145,14 +145,14 @@ RCT_EXTERN void RCTRegisterModule(Class); @end +#if !defined(RCT_REMOVE_LEGACY_ARCH) @interface RCTCxxBridge : RCTBridge // TODO(cjhopman): this seems unsafe unless we require that it is only called on the main js queue. @property (nonatomic, readonly) void *runtime; -#ifndef RCT_REMOVE_LEGACY_ARCH - (instancetype)initWithParentBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER __deprecated_msg("This API will be removed along with the legacy architecture."); -#endif // RCT_REMOVE_LEGACY_ARCH @end +#endif // RCT_REMOVE_LEGACY_ARCH diff --git a/packages/react-native/React/Base/RCTBridgeProxy.mm b/packages/react-native/React/Base/RCTBridgeProxy.mm index c840503be2ba..f7b343818772 100644 --- a/packages/react-native/React/Base/RCTBridgeProxy.mm +++ b/packages/react-native/React/Base/RCTBridgeProxy.mm @@ -387,7 +387,11 @@ - (RCTBridgeProxy *)object */ - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel; { +#ifndef RCT_REMOVE_LEGACY_ARCH return [RCTCxxBridge instanceMethodSignatureForSelector:sel]; +#else + return [RCTBridge instanceMethodSignatureForSelector:sel]; +#endif } - (void)forwardInvocation:(NSInvocation *)invocation diff --git a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm index a67f5bc646b9..075024114d76 100644 --- a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm +++ b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm @@ -1566,7 +1566,4 @@ - (RCTCallInvoker *)callInvokerForModuleData:(RCTModuleData *)moduleData @end -#else // RCT_REMOVE_LEGACY_ARCH -@implementation RCTCxxBridge -@end #endif // RCT_REMOVE_LEGACY_ARCH diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenterBridgeAdapter.h b/packages/react-native/React/Fabric/RCTSurfacePresenterBridgeAdapter.h index f3d8bbb0100d..27f622a906e2 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenterBridgeAdapter.h +++ b/packages/react-native/React/Fabric/RCTSurfacePresenterBridgeAdapter.h @@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_BEGIN @class RCTSurfacePresenter; @class RCTBridge; +#ifndef RCT_REMOVE_LEGACY_ARCH facebook::react::RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge); /* @@ -39,5 +40,6 @@ facebook::react::RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge) @property (nonatomic, weak) RCTBridge *bridge; @end +#endif NS_ASSUME_NONNULL_END diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenterBridgeAdapter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenterBridgeAdapter.mm index 73d3ed9b6794..3fcb2c83e7c2 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenterBridgeAdapter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenterBridgeAdapter.mm @@ -24,8 +24,8 @@ using namespace facebook::react; +#ifndef RCT_REMOVE_LEGACY_ARCH @interface RCTBridge () -- (std::shared_ptr)jsMessageThread; - (void)invokeAsync:(std::function &&)func; @end @@ -203,3 +203,4 @@ - (void)handleJavaScriptDidLoadNotification:(NSNotification *)notification } @end +#endif diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm index 4f709dcfd580..94be5df0c5c5 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm @@ -7,6 +7,7 @@ #import "RCTTurboModuleManager.h" #import "RCTInteropTurboModule.h" +#import "RCTTurboModule.h" #import #import @@ -165,23 +166,23 @@ bool isTurboModuleInstance(id module) return isTurboModuleClass([module class]); } -} // namespace +struct ModuleQueuePair { + id module; + dispatch_queue_t methodQueue; +}; // Fallback lookup since RCT class prefix is sometimes stripped in the existing NativeModule system. // This will be removed in the future. -static Class getFallbackClassFromName(const char *name) +Class getFallbackClassFromName(const char *name) { Class moduleClass = NSClassFromString([NSString stringWithUTF8String:name]); - if (!moduleClass) { + if (moduleClass == nil) { moduleClass = NSClassFromString([NSString stringWithFormat:@"RCT%s", name]); } return moduleClass; } -typedef struct { - id module; - dispatch_queue_t methodQueue; -} ModuleQueuePair; +} // namespace @implementation RCTTurboModuleManager { std::shared_ptr _jsInvoker;