From 922fee8cac73c916289a289124eee4051deecaa3 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Tue, 30 May 2023 02:56:44 -0700 Subject: [PATCH] Make RNTester use RCTAppDelegate (#37572) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37572 Currently, RNTester was using a completely custom AppDelegate and not leveraging the RCTAppDelegate we use in the OSS. This resulted in a misalignment between the two setups and duplicated work to test stuff internally furst and then in the OSS, with some more time needed to understand why one setup was working and the other wasn't. With this change, we are aligning the two, bringing RNTester closer to the OSS setup. There are still small differences, but we can iterate over those. ## Changelog: [iOS][Changed] - Make RNTester use RCTAppDelegate Reviewed By: cortinico Differential Revision: D46182888 fbshipit-source-id: 8c74e500281a2a39960a2ee21965605be80709ee --- .../AppDelegate/RCTLegacyInteropComponents.mm | 3 +- packages/rn-tester/RNTester/AppDelegate.h | 8 +- packages/rn-tester/RNTester/AppDelegate.mm | 271 ++---------------- .../RNTester/RNTesterTurboModuleProvider.h | 26 -- .../RNTester/RNTesterTurboModuleProvider.mm | 43 --- .../RNTesterPods.xcodeproj/project.pbxproj | 6 - packages/rn-tester/react-native.config.js | 1 + 7 files changed, 21 insertions(+), 337 deletions(-) delete mode 100644 packages/rn-tester/RNTester/RNTesterTurboModuleProvider.h delete mode 100644 packages/rn-tester/RNTester/RNTesterTurboModuleProvider.mm diff --git a/packages/react-native/Libraries/AppDelegate/RCTLegacyInteropComponents.mm b/packages/react-native/Libraries/AppDelegate/RCTLegacyInteropComponents.mm index d1d68376b08493..549e41a9b91b5f 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTLegacyInteropComponents.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTLegacyInteropComponents.mm @@ -1,3 +1,4 @@ + /* * Copyright (c) Meta Platforms, Inc. and affiliates. * @@ -11,7 +12,7 @@ @implementation RCTLegacyInteropComponents + (NSArray *)legacyInteropComponents { - return @[]; + return @[ @"RNTMyLegacyNativeView" ]; } @end diff --git a/packages/rn-tester/RNTester/AppDelegate.h b/packages/rn-tester/RNTester/AppDelegate.h index 55625d8693c2a8..d172167ee1d627 100644 --- a/packages/rn-tester/RNTester/AppDelegate.h +++ b/packages/rn-tester/RNTester/AppDelegate.h @@ -5,13 +5,9 @@ * LICENSE file in the root directory of this source tree. */ +#import #import -@class RCTBridge; - -@interface AppDelegate : UIResponder - -@property (nonatomic, strong) UIWindow *window; -@property (nonatomic, readonly) RCTBridge *bridge; +@interface AppDelegate : RCTAppDelegate @end diff --git a/packages/rn-tester/RNTester/AppDelegate.mm b/packages/rn-tester/RNTester/AppDelegate.mm index a04050d75f9127..f4e8d4006c5416 100644 --- a/packages/rn-tester/RNTester/AppDelegate.mm +++ b/packages/rn-tester/RNTester/AppDelegate.mm @@ -7,161 +7,30 @@ #import "AppDelegate.h" -#ifndef RCT_USE_HERMES -#if __has_include() -#define RCT_USE_HERMES 1 -#else -#define RCT_USE_HERMES 0 -#endif -#endif - -#ifdef RCT_NEW_ARCH_ENABLED -#ifndef RN_FABRIC_ENABLED -#define RN_FABRIC_ENABLED -#endif -#endif - -#if RCT_USE_HERMES -#import -#else -#import -#endif - -#import #import -#import -#import -#import -#import -#import -#import -#import -#import #import -#import -#import -#import -#import -#import -#import -#import - -#import +#import +#import #if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC #import #endif -#ifdef RN_FABRIC_ENABLED -#import -#import -#import -#import - -#import -#import -#import -#endif - #if RCT_NEW_ARCH_ENABLED +#import #import #endif -#if DEBUG -#ifdef FB_SONARKIT_ENABLED -#import -#import -#import -#import -#import -#import -#import -#endif -#endif - -#import -#import "RNTesterTurboModuleProvider.h" - -@interface RCTBridge () -- (std::shared_ptr)jsMessageThread; -- (void)invokeAsync:(std::function &&)func; -@end - -using namespace facebook::react; - -@interface AppDelegate () { - std::shared_ptr _runtimeScheduler; -#ifdef RN_FABRIC_ENABLED - RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; - std::shared_ptr _reactNativeConfig; - facebook::react::ContextContainer::Shared _contextContainer; -#endif -} -@end - -#if RCT_NEW_ARCH_ENABLED -/// Declare conformance to `RCTComponentViewFactoryComponentProvider` -@interface AppDelegate () -@end -#endif - -static NSString *const kRNConcurrentRoot = @"concurrentRoot"; - @implementation AppDelegate -#ifdef RN_FABRIC_ENABLED -- (instancetype)init +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - if (self = [super init]) { - _contextContainer = std::make_shared(); - _reactNativeConfig = std::make_shared(); - _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); - } - return self; -} -#endif - -- (BOOL)application:(__unused UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - RCTEnableTurboModule(YES); - - _bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; - - // Appetizer.io params check - NSDictionary *initProps = [self prepareInitialProps]; - -#if RCT_NEW_ARCH_ENABLED - [RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self; -#endif - -#ifdef RN_FABRIC_ENABLED - _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:_bridge contextContainer:_contextContainer]; - - _bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; - - UIView *rootView = [[RCTFabricSurfaceHostingProxyRootView alloc] initWithBridge:_bridge - moduleName:@"RNTesterApp" - initialProperties:initProps]; + self.moduleName = @"RNTesterApp"; + // You can add your custom initial props in the dictionary below. + // They will be passed down to the ViewController used by React Native. + self.initialProps = [self prepareInitialProps]; - [self registerPaperComponents:@[ @"RNTMyLegacyNativeView" ]]; -#else - UIView *rootView = [[RCTRootView alloc] initWithBridge:_bridge moduleName:@"RNTesterApp" initialProperties:initProps]; -#endif - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [UIViewController new]; - rootViewController.view = rootView; - self.window.rootViewController = rootViewController; - [self.window makeKeyAndVisible]; - [self initializeFlipper:application]; - - return YES; -} - -- (BOOL)concurrentRootEnabled -{ - // Switch this bool to turn on and off the concurrent root - return true; + return [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (NSDictionary *)prepareInitialProps @@ -173,34 +42,14 @@ - (NSDictionary *)prepareInitialProps initProps[@"exampleFromAppetizeParams"] = [NSString stringWithFormat:@"rntester://example/%@Example", _routeUri]; } -#ifdef RN_FABRIC_ENABLED - initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); -#endif - return initProps; } -- (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge +- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"js/RNTesterApp.ios"]; } -- (void)initializeFlipper:(UIApplication *)application -{ -#if DEBUG -#ifdef FB_SONARKIT_ENABLED - FlipperClient *client = [FlipperClient sharedClient]; - SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; - [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application - withDescriptorMapper:layoutDescriptorMapper]]; - [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; - [client addPlugin:[FlipperKitReactPlugin new]]; - [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; - [client start]; -#endif -#endif -} - - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options @@ -215,108 +64,20 @@ - (void)loadSourceForBridge:(RCTBridge *)bridge [RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge] onProgress:onProgress onComplete:loadCallback]; } -#pragma mark - RCTCxxBridgeDelegate - -// This function is called during -// `[[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];` -- (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge -{ - std::shared_ptr callInvoker = bridge.jsCallInvoker; - _runtimeScheduler = std::make_shared(RCTRuntimeExecutorFromBridge(bridge)); - -#ifdef RN_FABRIC_ENABLED - _contextContainer->erase("RuntimeScheduler"); - _contextContainer->insert("RuntimeScheduler", _runtimeScheduler); - callInvoker = std::make_shared(_runtimeScheduler); -#endif - - RCTTurboModuleManager *turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge - delegate:self - jsInvoker:callInvoker]; - [bridge setRCTTurboModuleRegistry:turboModuleManager]; - -#if RCT_DEV - /** - * Eagerly initialize RCTDevMenu so CMD + d, CMD + i, and CMD + r work. - * This is a stop gap until we have a system to eagerly init Turbo Modules. - */ - [turboModuleManager moduleForName:"RCTDevMenu"]; -#endif - - __weak __typeof(self) weakSelf = self; - -#if RCT_USE_HERMES - return std::make_unique( -#else - return std::make_unique( -#endif - facebook::react::RCTJSIExecutorRuntimeInstaller([weakSelf, bridge, turboModuleManager]( - facebook::jsi::Runtime &runtime) { - if (!bridge) { - return; - } - - __typeof(self) strongSelf = weakSelf; - if (strongSelf && strongSelf->_runtimeScheduler) { - facebook::react::RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, strongSelf->_runtimeScheduler); - } - - facebook::react::RuntimeExecutor syncRuntimeExecutor = - [&](std::function &&callback) { callback(runtime); }; - [turboModuleManager installJSBindingWithRuntimeExecutor:syncRuntimeExecutor]; - })); -} - -#pragma mark - RCTTurboModuleManagerDelegate - -- (Class)getModuleClassFromName:(const char *)name -{ - return facebook::react::RNTesterTurboModuleClassProvider(name); -} - - (std::shared_ptr)getTurboModule:(const std::string &)name jsInvoker:(std::shared_ptr)jsInvoker { - return facebook::react::RNTesterTurboModuleProvider(name, jsInvoker); -} - -- (id)getModuleInstanceFromClass:(Class)moduleClass -{ - // Set up the default RCTImageLoader and RCTNetworking modules. - if (moduleClass == RCTImageLoader.class) { - return [[moduleClass alloc] initWithRedirectDelegate:nil - loadersProvider:^NSArray> *(RCTModuleRegistry *) { - return @[ [RCTLocalAssetImageLoader new] ]; - } - decodersProvider:^NSArray> *(RCTModuleRegistry *) { - return @[ [RCTGIFImageDecoder new] ]; - }]; - } else if (moduleClass == RCTNetworking.class) { - return [[moduleClass alloc] initWithHandlersProvider:^NSArray> *(RCTModuleRegistry *) { - return @[ - [RCTHTTPRequestHandler new], - [RCTDataRequestHandler new], - [RCTFileRequestHandler new], - ]; - }]; + if (name == std::string([@"SampleTurboCxxModule" UTF8String])) { + return std::make_shared(jsInvoker); } - // No custom initializer here. - return [moduleClass new]; -} - -#pragma mark - Interop layer - -- (void)registerPaperComponents:(NSArray *)components -{ -#if RCT_NEW_ARCH_ENABLED - for (NSString *component in components) { - [RCTLegacyViewManagerInteropComponentView supportLegacyViewManagerWithName:component]; +#ifdef RCT_NEW_ARCH_ENABLED + if (name == std::string([@"NativeCxxModuleExampleCxx" UTF8String])) { + return std::make_shared(jsInvoker); } #endif + return nullptr; } -#pragma mark - Push Notifications - #if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC // Required to register for notifications diff --git a/packages/rn-tester/RNTester/RNTesterTurboModuleProvider.h b/packages/rn-tester/RNTester/RNTesterTurboModuleProvider.h deleted file mode 100644 index 3ca84512719340..00000000000000 --- a/packages/rn-tester/RNTester/RNTesterTurboModuleProvider.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 - -namespace facebook { -namespace react { - -/** - * Provide the TurboModule class for the given name. - */ -Class RNTesterTurboModuleClassProvider(const char *name); - -/** - * Provide a pure C++ instance of a TurboModule, specific to this app. - */ -std::shared_ptr RNTesterTurboModuleProvider( - const std::string &name, - std::shared_ptr jsInvoker); - -} // namespace react -} // namespace facebook diff --git a/packages/rn-tester/RNTester/RNTesterTurboModuleProvider.mm b/packages/rn-tester/RNTester/RNTesterTurboModuleProvider.mm deleted file mode 100644 index 32e5c3418013a9..00000000000000 --- a/packages/rn-tester/RNTester/RNTesterTurboModuleProvider.mm +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 "RNTesterTurboModuleProvider.h" - -#ifdef RCT_NEW_ARCH_ENABLED -#import -#endif -#import -#import -#import - -// NOTE: This entire file should be codegen'ed. - -namespace facebook { -namespace react { - -Class RNTesterTurboModuleClassProvider(const char *name) -{ - return RCTCoreModulesClassProvider(name); -} - -std::shared_ptr RNTesterTurboModuleProvider( - const std::string &name, - std::shared_ptr jsInvoker) -{ - if (name == "SampleTurboCxxModule") { - return std::make_shared(jsInvoker); - } -#ifdef RCT_NEW_ARCH_ENABLED - if (name == "NativeCxxModuleExampleCxx") { - return std::make_shared(jsInvoker); - } -#endif - return nullptr; -} - -} // namespace react -} // namespace facebook diff --git a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj index 4e5505f231fb69..01af6ae1065c2d 100644 --- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj +++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj @@ -15,7 +15,6 @@ 383889DA23A7398900D06C3E /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */; }; 3D2AFAF51D646CF80089D1A3 /* legacy_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */; }; 5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C60EB1B226440DB0018C04F /* AppDelegate.mm */; }; - 5CB07C9B226467E60039471C /* RNTesterTurboModuleProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */; }; 8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */; }; 953D44E0A849F5064163EA24 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F4A7C4C85AB0198A25D51E4 /* libPods-RNTesterIntegrationTests.a */; }; BE3BEE3556275C62F33864C8 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6144DEEE56C6C17B301A90E4 /* libPods-RNTesterUnitTests.a */; }; @@ -96,8 +95,6 @@ 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "legacy_image@2x.png"; path = "RNTester/legacy_image@2x.png"; sourceTree = ""; }; 4F4A7C4C85AB0198A25D51E4 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 5C60EB1B226440DB0018C04F /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNTester/AppDelegate.mm; sourceTree = ""; }; - 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RNTesterTurboModuleProvider.mm; path = RNTester/RNTesterTurboModuleProvider.mm; sourceTree = ""; }; - 5CB07C9A226467E60039471C /* RNTesterTurboModuleProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNTesterTurboModuleProvider.h; path = RNTester/RNTesterTurboModuleProvider.h; sourceTree = ""; }; 6144DEEE56C6C17B301A90E4 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 7FC437025B5EE3899315628B /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = ""; }; 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNTester/LaunchScreen.storyboard; sourceTree = ""; }; @@ -230,8 +227,6 @@ E771AEEA22B44E3100EA1189 /* Info.plist */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 5C60EB1B226440DB0018C04F /* AppDelegate.mm */, - 5CB07C9A226467E60039471C /* RNTesterTurboModuleProvider.h */, - 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */, 13B07FB71A68108700A75B9A /* main.m */, 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */, 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */, @@ -762,7 +757,6 @@ buildActionMask = 2147483647; files = ( 272E6B3F1BEA849E001FCF37 /* UpdatePropertiesExampleView.m in Sources */, - 5CB07C9B226467E60039471C /* RNTesterTurboModuleProvider.mm in Sources */, 27F441EC1BEBE5030039B79C /* FlexibleSizeExampleView.m in Sources */, 5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, diff --git a/packages/rn-tester/react-native.config.js b/packages/rn-tester/react-native.config.js index 099000c501058d..b3ad6adb66f61b 100644 --- a/packages/rn-tester/react-native.config.js +++ b/packages/rn-tester/react-native.config.js @@ -28,6 +28,7 @@ module.exports = { project: { ios: { sourceDir: '.', + unstable_reactLegacyComponentNames: ['RNTMyLegacyNativeView'], }, android: { sourceDir: '../../',