Skip to content

Commit

Permalink
feat: improve RCTAppDelegate usage for brownfield (#46625)
Browse files Browse the repository at this point in the history
Summary:
This PR improves the usage of `RCTAppDelegate` for brownfield scenarios.

Currently, when we want to integrate React Native with a brownfield app users might not want to initialize React Native in the main window. They may want to create it later.

Example usage:

```swift
class AppDelegate: RCTAppDelegate {
   override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
      // Disable automatically creating react native window
      self.automaticallyLoadReactNativeWindow = false

      return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
```

```swift
import Foundation
import React
import React_RCTAppDelegate

class SettingsViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    self.view = (RCTSharedApplication()?.delegate as? RCTAppDelegate)?.rootViewFactory .view(withModuleName: "Settings", initialProperties: [:])
  }
}
```

## Changelog:

[IOS] [ADDED] - improve RCTAppDelegate usage for brownfield, add `automaticallyLoadReactNativeWindow` flag

Pull Request resolved: #46625

Test Plan: CI Green

Reviewed By: cortinico

Differential Revision: D63325397

Pulled By: cipolleschi

fbshipit-source-id: 1361bda5fcd91f4933219871c64a84a83c281c34
  • Loading branch information
okwasniewski authored and facebook-github-bot committed Sep 26, 2024
1 parent 10a33e0 commit 391680f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
3 changes: 3 additions & 0 deletions packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong, nullable) NSDictionary *initialProps;
@property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory;

/// If `automaticallyLoadReactNativeWindow` is set to `true`, the React Native window will be loaded automatically.
@property (nonatomic, assign) BOOL automaticallyLoadReactNativeWindow;

@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;

/**
Expand Down
32 changes: 23 additions & 9 deletions packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <React/RCTUtils.h>
#import <ReactCommon/RCTHost.h>
#include <UIKit/UIKit.h>
#import <objc/runtime.h>
#import <react/featureflags/ReactNativeFeatureFlags.h>
#import <react/featureflags/ReactNativeFeatureFlagsDefaults.h>
Expand All @@ -38,6 +39,14 @@ @interface RCTAppDelegate () <RCTComponentViewFactoryComponentProvider, RCTHostD

@implementation RCTAppDelegate

- (instancetype)init
{
if (self = [super init]) {
_automaticallyLoadReactNativeWindow = YES;
}
return self;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self _setUpFeatureFlags];
Expand All @@ -47,23 +56,28 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
RCTAppSetupPrepareApp(application, self.turboModuleEnabled);

self.rootViewFactory = [self createRCTRootViewFactory];
if (self.newArchEnabled || self.fabricEnabled) {
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = 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];

if (self.newArchEnabled || self.fabricEnabled) {
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
}

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [self createRootViewController];
[self setRootView:rootView toRootViewController:rootViewController];
self.window.rootViewController = rootViewController;
self.window.windowScene.delegate = self;
[self.window makeKeyAndVisible];

return YES;
_window.rootViewController = rootViewController;
[_window makeKeyAndVisible];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
Expand Down

0 comments on commit 391680f

Please sign in to comment.