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

0.76: TurboModuleRegistry.getEnforcing error when creating a new bridge (iOS - new Arch) #48760

Closed
fbp93 opened this issue Jan 17, 2025 · 5 comments
Labels

Comments

@fbp93
Copy link

fbp93 commented Jan 17, 2025

Description

Hi 👋
My app needs to perform a series of operations on a separate thread, and for this reason, during the setup phase, we generate an additional RCTBridge by passing it a jsbundle. After updating to version 0.76 and enabling the new architecture, this setup stopped working, as if the bundle is "broken."
I created an example project that reproduces the setup flow, I'll try to give you here more context:

  • The app starts and invokes the native API startWorker
  • The WorkerManager component takes care to inizialize a new RCTBridge starting from the bundle worker.jsbundle, which is generated from Worker.js file.
  • As soon as the bundle is loaded I start receiving the following errors:
Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'PlatformConstants' could not be found. Verify that a module by this name is registered in the native binary., js engine: hermes
Unhandled JS Exception: TurboModuleRegistry.getEnforcing(...): 'PlatformConstants' could not be found. Verify that a module by this name is registered in the native binary.
E0117 15:55:27.332340 1836544000 NativeToJsBridge.cpp:186] Attempting to call JS function on a bad application bundle: RCTLog.logIfNoNativeHook()

If I opt-out the new arch with RCT_NEW_ARCH_ENABLED=0 bundle exec pod install everything seems working fine. Also using an empty bundle seems fine, but importing react native breaks everything.

Looking in the web I found a discussion for a similar issue with android (different context but same error) so I was wondering if something is broken also iOS side.
Can you help me to understand if there is any issue or we are doing something wrong with the additional bridge creation? Thanks 🙏

Steps to reproduce

  1. Install and the run the application
  2. Launch iOS with XCode and see the errors in the console
  3. Disable the new arch with RCT_NEW_ARCH_ENABLED=0 bundle exec pod install
  4. Launch again the app and see that everything works fine

React Native Version

0.76.6

Affected Platforms

Runtime - iOS

Output of npx react-native info

System:
  OS: macOS 14.6.1
  CPU: (10) arm64 Apple M1 Pro
  Memory: 106.58 MB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.17.0
    path: ~/Library/Caches/fnm_multishells/33278_1736765256951/bin/node
  Yarn:
    version: 3.6.4
    path: ~/Library/Caches/fnm_multishells/33278_1736765256951/bin/yarn
  npm:
    version: 10.8.2
    path: ~/Library/Caches/fnm_multishells/33278_1736765256951/bin/npm
  Watchman:
    version: 2024.11.18.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods: Not Found
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.0
      - iOS 18.0
      - macOS 15.0
      - tvOS 18.0
      - visionOS 2.0
      - watchOS 11.0
  Android SDK:
    API Levels:
      - "23"
      - "28"
      - "29"
      - "30"
      - "31"
      - "33"
      - "34"
      - "35"
    Build Tools:
      - 30.0.3
      - 31.0.0
      - 33.0.0
      - 33.0.1
      - 34.0.0
      - 35.0.0
    System Images:
      - android-28 | Google ARM64-V8a Play ARM 64 v8a
      - android-34 | Google APIs ARM 64 v8a
      - android-34 | Google Play ARM 64 v8a
    Android NDK: 25.1.8937393
IDEs:
  Android Studio: 2022.3 AI-223.8836.35.2231.10671973
  Xcode:
    version: 16.0/16A242
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.13
    path: /opt/homebrew/Cellar/openjdk@17/17.0.13/bin/javac
  Ruby:
    version: 3.0.0
    path: /Users/work/.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: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'PlatformConstants' could not be found. Verify that a module by this name is registered in the native binary., js engine: hermes
Unhandled JS Exception: TurboModuleRegistry.getEnforcing(...): 'PlatformConstants' could not be found. Verify that a module by this name is registered in the native binary.
E0117 15:55:27.332340 1836544000 NativeToJsBridge.cpp:186] Attempting to call JS function on a bad application bundle: RCTLog.logIfNoNativeHook()

Reproducer

https://github.com/fbp93/rn0.76-bridge-issue/tree/main

Screenshots and Videos

No response

@fbp93
Copy link
Author

fbp93 commented Jan 17, 2025

cc @cipolleschi 🙏

@react-native-bot react-native-bot added the Platform: iOS iOS applications. label Jan 17, 2025
@okwasniewski
Copy link
Contributor

Hey @fbp93

You should read about Turbo Modules, the new module system: https://reactnative.dev/docs/next/turbo-native-modules-introduction you are currently using legacy APIs in your WorkerManager.

@fbp93
Copy link
Author

fbp93 commented Jan 19, 2025

@okwasniewski I know about TurboModules, but I think they can be used to interact with native code. My goal is slightly different, I need to load a different js bundle into a new react context and they the two react instances are gonna talk each others. Am I missing something? Also the RCTBridge API is not marked as deprecated

@cipolleschi
Copy link
Contributor

This setup is incompatible with the New Architecture.

One of the new architecture principle is being Bridgeless. We are tearing down the bridge because it was a bottleneck for many applications and it prevented from running stuff on different threads. In fact, people developed solutions like yours, creating multiple bridges to get around that limitation.

With the New Architecture, you don't need to have multiple React Native instances. As @okwasniewski was mentioning, you can have turbomodules that shares memory directly between JS and native so the serialization bottleneck is gone.

Alternatively, there is still the possibility to have multiple instances of React Native running, but in the New Architecture you'll have to replicate all the initialization code that is in the RCTAppDelegate to initialize a new RCTHost and a new RCTInstance. In 0.78, this will be dramatically simplified by the RCTReactNativeFactory.

The RCTBridge is not deprecated (yet) because we are still supporting the old architecture until most the ecosystem migrates away from it. In fact, we have interop layers that mimics the old architecture to support the migration of most app.

@fbp93
Copy link
Author

fbp93 commented Jan 20, 2025

@cipolleschi Thanks for the explanation 🙏

@fbp93 fbp93 closed this as completed Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants