Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make RNTester use RCTAppDelegate #37572

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
Expand All @@ -11,7 +12,7 @@ @implementation RCTLegacyInteropComponents

+ (NSArray<NSString *> *)legacyInteropComponents
{
return @[];
return @[ @"RNTMyLegacyNativeView" ];
}

@end
8 changes: 2 additions & 6 deletions packages/rn-tester/RNTester/AppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

#import <RCTAppDelegate.h>
#import <UIKit/UIKit.h>

@class RCTBridge;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, readonly) RCTBridge *bridge;
@interface AppDelegate : RCTAppDelegate

@end
271 changes: 16 additions & 255 deletions packages/rn-tester/RNTester/AppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,161 +7,30 @@

#import "AppDelegate.h"

#ifndef RCT_USE_HERMES
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
#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 <reacthermes/HermesExecutorFactory.h>
#else
#import <React/JSCExecutorFactory.h>
#endif

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTDataRequestHandler.h>
#import <React/RCTFileRequestHandler.h>
#import <React/RCTGIFImageDecoder.h>
#import <React/RCTHTTPRequestHandler.h>
#import <React/RCTImageLoader.h>
#import <React/RCTJSIExecutorRuntimeInstaller.h>
#import <React/RCTJavaScriptLoader.h>
#import <React/RCTLinkingManager.h>
#import <React/RCTLocalAssetImageLoader.h>
#import <React/RCTNetworking.h>
#import <React/RCTRootView.h>
#import <React/RCTRuntimeExecutorFromBridge.h>
#import <ReactCommon/RuntimeExecutor.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>

#import <cxxreact/JSExecutor.h>
#import <ReactCommon/RCTSampleTurboModule.h>
#import <ReactCommon/SampleTurboCxxModule.h>

#if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC
#import <React/RCTPushNotificationManager.h>
#endif

#ifdef RN_FABRIC_ENABLED
#import <React/RCTComponentViewFactory.h>
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>

#import <React/RCTLegacyViewManagerInteropComponentView.h>
#import <react/config/ReactNativeConfig.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
#endif

#if RCT_NEW_ARCH_ENABLED
#import <NativeCxxModuleExample/NativeCxxModuleExample.h>
#import <RNTMyNativeViewComponentView.h>
#endif

#if DEBUG
#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitLayoutPlugin/SKDescriptorMapper.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#endif
#endif

#import <ReactCommon/RCTTurboModuleManager.h>
#import "RNTesterTurboModuleProvider.h"

@interface RCTBridge ()
- (std::shared_ptr<facebook::react::MessageQueueThread>)jsMessageThread;
- (void)invokeAsync:(std::function<void()> &&)func;
@end

using namespace facebook::react;

@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
#ifdef RN_FABRIC_ENABLED
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
#endif
}
@end

#if RCT_NEW_ARCH_ENABLED
/// Declare conformance to `RCTComponentViewFactoryComponentProvider`
@interface AppDelegate () <RCTComponentViewFactoryComponentProvider>
@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<facebook::react::ContextContainer const>();
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
_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
Expand All @@ -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<UIApplicationOpenURLOptionsKey, id> *)options
Expand All @@ -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<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
std::shared_ptr<facebook::react::CallInvoker> callInvoker = bridge.jsCallInvoker;
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));

#ifdef RN_FABRIC_ENABLED
_contextContainer->erase("RuntimeScheduler");
_contextContainer->insert("RuntimeScheduler", _runtimeScheduler);
callInvoker = std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(_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<facebook::react::HermesExecutorFactory>(
#else
return std::make_unique<facebook::react::JSCExecutorFactory>(
#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<void(facebook::jsi::Runtime & runtime_)> &&callback) { callback(runtime); };
[turboModuleManager installJSBindingWithRuntimeExecutor:syncRuntimeExecutor];
}));
}

#pragma mark - RCTTurboModuleManagerDelegate

- (Class)getModuleClassFromName:(const char *)name
{
return facebook::react::RNTesterTurboModuleClassProvider(name);
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
return facebook::react::RNTesterTurboModuleProvider(name, jsInvoker);
}

- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
// Set up the default RCTImageLoader and RCTNetworking modules.
if (moduleClass == RCTImageLoader.class) {
return [[moduleClass alloc] initWithRedirectDelegate:nil
loadersProvider:^NSArray<id<RCTImageURLLoader>> *(RCTModuleRegistry *) {
return @[ [RCTLocalAssetImageLoader new] ];
}
decodersProvider:^NSArray<id<RCTImageDataDecoder>> *(RCTModuleRegistry *) {
return @[ [RCTGIFImageDecoder new] ];
}];
} else if (moduleClass == RCTNetworking.class) {
return [[moduleClass alloc] initWithHandlersProvider:^NSArray<id<RCTURLRequestHandler>> *(RCTModuleRegistry *) {
return @[
[RCTHTTPRequestHandler new],
[RCTDataRequestHandler new],
[RCTFileRequestHandler new],
];
}];
if (name == std::string([@"SampleTurboCxxModule" UTF8String])) {
return std::make_shared<facebook::react::SampleTurboCxxModule>(jsInvoker);
}
// No custom initializer here.
return [moduleClass new];
}

#pragma mark - Interop layer

- (void)registerPaperComponents:(NSArray<NSString *> *)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<facebook::react::NativeCxxModuleExample>(jsInvoker);
}
#endif
return nullptr;
}

#pragma mark - Push Notifications

#if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC

// Required to register for notifications
Expand Down
26 changes: 0 additions & 26 deletions packages/rn-tester/RNTester/RNTesterTurboModuleProvider.h

This file was deleted.

Loading