microsoft/rnx-kit

react-native-host does not render when new arch is enabled

gabrieldonadel opened this issue · 2 comments

What happened?

When using @rnx-kit/react-native-host with the old arch the app renders as expected but when activating the new arch on iOS

old arch new arch
Screen.Recording.2023-12-21.at.16.35.32.mov
Screen.Recording.2023-12-21.at.16.29.59.mov

Tested both on 0.72 (using @rnx-kit/react-native-host@0.2.8) and 0.73 (using @rnx-kit/react-native-host@0.3.1)

Affected Package

@rnx-kit/react-native-host

Version

0.2.8

Which platforms are you seeing this issue on?

  • Android
  • iOS
  • macOS
  • Windows

System Information

System:
  OS: macOS 14.0
  CPU: (12) arm64 Apple M2 Max
  Memory: 298.05 MB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.18.2
    path: ~/.volta/tools/image/node/18.18.2/bin/node
  Yarn:
    version: 1.22.19
    path: ~/.volta/tools/image/yarn/1.22.19/bin/yarn
  npm:
    version: 9.8.1
    path: ~/.volta/tools/image/node/18.18.2/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.13.0
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.2
      - iOS 17.2
      - macOS 14.2
      - tvOS 17.2
      - visionOS 1.0
      - watchOS 10.2
  Android SDK:
    API Levels:
      - "22"
      - "26"
      - "30"
      - "31"
      - "33"
      - "34"
    Build Tools:
      - 26.0.3
      - 30.0.3
      - 31.0.0
      - 33.0.0
      - 33.0.1
      - 33.0.2
      - 34.0.0
    System Images:
      - android-22 | ARM 64 v8a
      - android-26 | Google APIs Intel x86_64 Atom
      - android-30 | ARM 64 v8a
      - android-33 | Google APIs ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2022.3 AI-223.8836.35.2231.10811636
  Xcode:
    version: 15.2/15C5500c
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.8
    path: /usr/bin/javac
  Ruby:
    version: 2.7.8
    path: /Users/gabriel/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react: Not Found
  react-native: Not Found
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: true

Steps to Reproduce

Here is minimal repo with the necessary changes -> https://github.com/gabrieldonadel/react-native-host-example, but it's possible to replicate this by updating your AppDelegate to:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  
  ReactNativeHost *host = [[ReactNativeHost alloc] initWithConfig:self];
  UIView *rootView = [host viewWithModuleName:@"RN072"
                                initialProperties:[self prepareInitialProps]];

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

  return YES;
}

Code of Conduct

  • I agree to follow this project's Code of Conduct

Hi @gabrieldonadel, I dunno how old arch works in this case because what's happening is that ReactNativeHost gets deallocated when returning from application:didFinishLaunchingWithOptions:. We need to retain a reference, e.g.:

diff --git a/ios/RN072/AppDelegate.m b/ios/RN072/AppDelegate.m
index b4c4819..3df740e 100644
--- a/ios/RN072/AppDelegate.m
+++ b/ios/RN072/AppDelegate.m
@@ -5,14 +5,16 @@

 static NSString *const kRNConcurrentRoot = @"concurrentRoot";

-@implementation AppDelegate
+@implementation AppDelegate {
+  ReactNativeHost *host_;
+}

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {
       self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

-    ReactNativeHost *host = [[ReactNativeHost alloc] initWithConfig:self];
-    UIView *rootView = [host viewWithModuleName:@"RN072"
+    host_ = [[ReactNativeHost alloc] initWithConfig:self];
+    UIView *rootView = [host_ viewWithModuleName:@"RN072"
                                 initialProperties:[self prepareInitialProps]];

   UIViewController *rootViewController = [UIViewController new];

For future reference, an out-of-place warning in facebook::react::Scheduler led me down this path:

W1222 11:31:55.887077 67830336 Scheduler.cpp:144] Scheduler::~Scheduler() was called (address: 0x600003308d20).

Hi @tido64, thanks for the quick response. Indeed that was the issue 🤦‍♂️, everything works as expected