Skip to content
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
90 changes: 90 additions & 0 deletions RCTAppDelegate.h
Original file line number Diff line number Diff line change
@@ -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 <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;

- (UISceneConfiguration *)application:(UIApplication *)application
configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession
options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13.0));

@end

NS_ASSUME_NONNULL_END
100 changes: 100 additions & 0 deletions RCTAppDelegate.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* 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;
}

- (UISceneConfiguration *)application:(UIApplication *)application
configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession
options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13.0))
{
UISceneConfiguration *configuration = [[UISceneConfiguration alloc] initWithName:@"Default Configuration"
sessionRole:connectingSceneSession.role];
configuration.delegateClass = NSClassFromString(@"RCTSceneDelegate");
return configuration;
}

@end
22 changes: 22 additions & 0 deletions RCTSceneDelegate.h
Original file line number Diff line number Diff line change
@@ -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.
*/

#import <UIKit/UIKit.h>

@class RCTReactNativeFactory;

NS_ASSUME_NONNULL_BEGIN

API_AVAILABLE(ios(13.0))
@interface RCTSceneDelegate : UIResponder <UIWindowSceneDelegate>

@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, weak) RCTReactNativeFactory *reactNativeFactory;

@end

NS_ASSUME_NONNULL_END
60 changes: 60 additions & 0 deletions RCTSceneDelegate.mm
Original file line number Diff line number Diff line change
@@ -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 "RCTSceneDelegate.h"
#import "RCTReactNativeFactory.h"
#import "RCTRootViewFactory.h"

@implementation RCTSceneDelegate

- (void)scene:(UIScene *)scene
willConnectToSession:(UISceneSession *)session
options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0))
{
if (![scene isKindOfClass:[UIWindowScene class]]) {
return;
}

UIWindowScene *windowScene = (UIWindowScene *)scene;

self.window = [[UIWindow alloc] initWithWindowScene:windowScene];

if (self.reactNativeFactory) {
UIView *rootView = [self.reactNativeFactory.rootViewFactory
viewWithModuleName:self.reactNativeFactory.rootViewFactory.moduleName
initialProperties:self.reactNativeFactory.rootViewFactory.initialProperties
launchOptions:connectionOptions.notificationResponse.notification.request.content.userInfo];

UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
}

[self.window makeKeyAndVisible];
}

- (void)sceneDidDisconnect:(UIScene *)scene API_AVAILABLE(ios(13.0))
{
}

- (void)sceneDidBecomeActive:(UIScene *)scene API_AVAILABLE(ios(13.0))
{
}

- (void)sceneWillResignActive:(UIScene *)scene API_AVAILABLE(ios(13.0))
{
}

- (void)sceneWillEnterForeground:(UIScene *)scene API_AVAILABLE(ios(13.0))
{
}

- (void)sceneDidEnterBackground:(UIScene *)scene API_AVAILABLE(ios(13.0))
{
}

@end
17 changes: 17 additions & 0 deletions packages/rn-tester/RNTester/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,22 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>RCTSceneDelegate</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>
Loading