Skip to content

Commit

Permalink
feat: introduce new method to RCTAppDelegate
Browse files Browse the repository at this point in the history
  • Loading branch information
okwasniewski committed Jan 12, 2024
1 parent 30a914f commit fab7056
Show file tree
Hide file tree
Showing 17 changed files with 173 additions and 536 deletions.
5 changes: 4 additions & 1 deletion packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,11 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)bridgelessEnabled;

/// Return the bundle URL for the main bundle.
- (NSURL *)bundleURL;
- (NSURL *__nullable)bundleURL;

- (UIView *)viewWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary*)initialProperties launchOptions:(NSDictionary*)launchOptions;

@end

NS_ASSUME_NONNULL_END

92 changes: 52 additions & 40 deletions packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
#import <react/runtime/JSRuntimeFactory.h>


static NSString *const kRNConcurrentRoot = @"concurrentRoot";

@interface RCTAppDelegate () <
Expand Down Expand Up @@ -83,51 +84,16 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
{
RCTSetNewArchEnabled([self newArchEnabled]);
BOOL enableTM = self.turboModuleEnabled;
BOOL fabricEnabled = self.fabricEnabled;
BOOL enableBridgeless = self.bridgelessEnabled;

NSDictionary *initProps = updateInitialProps([self prepareInitialProps], fabricEnabled);

RCTAppSetupPrepareApp(application, enableTM, *_reactNativeConfig);

UIView *rootView;
if (enableBridgeless) {
// Enable native view config interop only if both bridgeless mode and Fabric is enabled.
RCTSetUseNativeViewConfigsInBridgelessMode(fabricEnabled);

// Enable TurboModule interop by default in Bridgeless mode
RCTEnableTurboModuleInterop(YES);
RCTEnableTurboModuleInteropBridgeProxy(YES);

[self createReactHost];
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
RCTFabricSurface *surface = [_reactHost createSurfaceWithModuleName:self.moduleName initialProperties:initProps];

RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView = [[RCTSurfaceHostingProxyRootView alloc]
initWithSurface:surface
sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact];

rootView = (RCTRootView *)surfaceHostingProxyRootView;
} else {
if (!self.bridge) {
self.bridge = [self createBridgeWithDelegate:self launchOptions:launchOptions];
}
if ([self newArchEnabled]) {
self.bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:self.bridge
contextContainer:_contextContainer];
self.bridge.surfacePresenter = self.bridgeAdapter.surfacePresenter;

[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
}
rootView = [self createRootViewWithBridge:self.bridge moduleName:self.moduleName initProps:initProps];
}

[self customizeRootView:(RCTRootView *)rootView];

#if TARGET_OS_VISION
self.window = [[UIWindow alloc] initWithFrame:RCTForegroundWindow().bounds];
/// Bail out of UIWindow initializaiton to support multi-window scenarios in SwiftUI lifecycle.
return YES;
#else
UIView* rootView = [self viewWithModuleName:self.moduleName initialProperties:[self prepareInitialProps] launchOptions:launchOptions];

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
#endif

UIViewController *rootViewController = [self createRootViewController];
[self setRootView:rootView toRootViewController:rootViewController];
Expand All @@ -136,13 +102,59 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
[self.window makeKeyAndVisible];

return YES;
#endif
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Noop
}

- (UIView *)viewWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary*)initialProperties launchOptions:(NSDictionary*)launchOptions {
BOOL fabricEnabled = self.fabricEnabled;
BOOL enableBridgeless = self.bridgelessEnabled;

NSDictionary *initProps = updateInitialProps(initialProperties, fabricEnabled);

UIView *rootView;
if (enableBridgeless) {
// Enable native view config interop only if both bridgeless mode and Fabric is enabled.
RCTSetUseNativeViewConfigsInBridgelessMode(self.fabricEnabled);

// Enable TurboModule interop by default in Bridgeless mode
RCTEnableTurboModuleInterop(YES);
RCTEnableTurboModuleInteropBridgeProxy(YES);

[self createReactHost];
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
RCTFabricSurface *surface = [_reactHost createSurfaceWithModuleName:self.moduleName initialProperties:initProps];

RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView = [[RCTSurfaceHostingProxyRootView alloc]
initWithSurface:surface
sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact];

rootView = (RCTRootView *)surfaceHostingProxyRootView;
} else {
if (!self.bridge) {
self.bridge = [self createBridgeWithDelegate:self launchOptions:launchOptions];
}
if ([self newArchEnabled]) {
if (!self.bridgeAdapter) {
self.bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:self.bridge
contextContainer:_contextContainer];
self.bridge.surfacePresenter = self.bridgeAdapter.surfacePresenter;

[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
}
}
rootView = [self createRootViewWithBridge:self.bridge moduleName:moduleName initProps:initProps];
}

[self customizeRootView:(RCTRootView *)rootView];

return rootView;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
[NSException raise:@"RCTBridgeDelegate::sourceURLForBridge not implemented"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#elif __has_include(<reacthermes/HermesExecutorFactory.h>)
#import <reacthermes/HermesExecutorFactory.h>
#endif
#else // USE_HERMES
#elif __has_include(<React/JSCExecutorFactory.h>) // USE_HERMES
#import <React/JSCExecutorFactory.h>
#endif // USE_HERMES

Expand Down
12 changes: 0 additions & 12 deletions packages/react-native/Libraries/AppDelegate/RCTReactController.h

This file was deleted.

120 changes: 0 additions & 120 deletions packages/react-native/Libraries/AppDelegate/RCTReactController.mm

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>

@interface RCTReactViewController : UIViewController

@property (nonatomic, strong) NSString *_Nonnull moduleName;
@property (nonatomic, strong) NSDictionary *_Nullable initialProps;

- (instancetype _Nonnull)initWithModuleName:(NSString *_Nonnull)moduleName
initProps:(NSDictionary *_Nullable)initProps;

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#import "RCTReactViewController.h"
#import <React/RCTUtils.h>

#import "RCTAppDelegate.h"

@implementation RCTReactViewController

- (instancetype)initWithModuleName:(NSString *)moduleName initProps:(NSDictionary *)initProps {
if (self = [super init]) {
_moduleName = moduleName;
_initialProps = initProps;
}
return self;
}

- (void)loadView {
id<UIApplicationDelegate> appDelegate = RCTSharedApplication().delegate;
if ([appDelegate respondsToSelector:@selector(viewWithModuleName:initialProperties:launchOptions:)]) {
RCTAppDelegate *delegate = (RCTAppDelegate *)appDelegate;
self.view = [delegate viewWithModuleName:_moduleName initialProperties:_initialProps launchOptions:@{}];
} else {
[NSException raise:@"UIApplicationDelegate:viewWithModuleName:initialProperties:launchOptions: not implemented"
format:@"Make sure you subclass RCTAppDelegate"];
}
}

@end

This file was deleted.

Loading

0 comments on commit fab7056

Please sign in to comment.