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

[New Architecture][iOS][Bridgeless] Native module methods not visible in JS #46779

Closed
WoLewicki opened this issue Oct 2, 2024 · 3 comments
Closed
Labels
p: Software Mansion Partner: Software Mansion Partner Platform: iOS iOS applications. Resolution: Answered When the issue is resolved with a simple answer Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)

Comments

@WoLewicki
Copy link
Contributor

Description

When using Native Modules on new architecture in bridgeless mode with interop layer, calling Object.keys on that module does not print the available methods on that module, whereas it works in bridge mode.

Steps to reproduce

  1. Install the app on iOS
  2. See that the printed properties differ when you use bridge and bridgeless mode

React Native Version

0.75.3

Affected Platforms

Runtime - iOS

Areas

TurboModule - The New Native Module System, Bridgeless - The New Initialization Flow

Output of npx react-native info

System:
  OS: macOS 14.5
  CPU: (12) arm64 Apple M3 Pro
  Memory: 113.39 MB / 18.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.15.1
    path: ~/.nvm/versions/node/v20.15.1/bin/node
  Yarn:
    version: 3.6.4
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.7.0
    path: ~/.nvm/versions/node/v20.15.1/bin/npm
  Watchman:
    version: 2024.09.23.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /Users/wojciechlewicki/.rvm/gems/ruby-3.2.1/bin/pod
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:
      - "26"
      - "27"
      - "28"
      - "29"
      - "30"
      - "31"
      - "32"
      - "33"
      - "34"
    Build Tools:
      - 28.0.3
      - 29.0.2
      - 30.0.2
      - 30.0.3
      - 31.0.0
      - 32.0.0
      - 32.1.0
      - 33.0.0
      - 33.0.1
      - 34.0.0
    System Images:
      - android-28 | Google ARM64-V8a Play ARM 64 v8a
      - android-29 | Google Play ARM 64 v8a
      - android-31 | Google Play ARM 64 v8a
      - android-32 | Google APIs ARM 64 v8a
      - android-33 | Google Play ARM 64 v8a
      - android-34 | Google Play ARM 64 v8a
      - android-35 | Google Play ARM 64 v8a
    Android NDK: 22.1.7171670
IDEs:
  Android Studio: 2024.1 AI-241.18034.62.2411.12169540
  Xcode:
    version: 16.0/16A242d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 18.0.2
    path: /opt/homebrew/opt/openjdk@18/bin/javac
  Ruby:
    version: 3.2.1
    path: /Users/wojciechlewicki/.rvm/rubies/ruby-3.2.1/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.75.3
    wanted: 0.75.3
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

Bridgeless:
`properties:  []`
Bridge:
`properties:  ["metaGetAll", "jsonGetAll", "preferencesSetBool", "preferencesSetString", "preferencesGetAll", "preferencesClearAll", "eventsNotifyReady", "eventsGetListeners", "eventsPing", "eventsAddListener", "eventsRemoveListener", "addListener", "removeListeners", "initializeApp", "setLogLevel", "setAutomaticDataCollectionEnabled", "deleteApp", "NATIVE_FIREBASE_APPS", "FIREBASE_RAW_JSON", "getConstants"]`

Reproducer

https://github.com/WoLewicki/reproducer-react-native/tree/%40wolewicki/bridgeless-constants

Screenshots and Videos

No response

@WoLewicki WoLewicki added Needs: Triage 🔍 Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules) labels Oct 2, 2024
@facebook-github-bot facebook-github-bot added p: Software Mansion Partner: Software Mansion Partner labels Oct 2, 2024
@react-native-bot react-native-bot added the Platform: iOS iOS applications. label Oct 2, 2024
@cipolleschi
Copy link
Contributor

After some internal investigation, we realized that this behavior is like that by design. We designed the TurboModule system with the goal of lazy loading, so we don’t have to load all the modules in memory when the app is launched. This should let your app start faster.

One of the trade-offs of this solution is that you cannot call Object.keys on a native module right away, because not all the keys might be available immediately.

Instead, you can read them by leveraging the inheritance. You can call Object.keys on the native module's prototype and the result should be the same as before.

- for prop in Object.keys(nativeModule) {
+ for prop in Object.keys(Object.getPrototypeOf(nativeModule)) {
 // use the prop here
}

@cipolleschi cipolleschi added the Resolution: Answered When the issue is resolved with a simple answer label Oct 21, 2024
@WoLewicki
Copy link
Contributor Author

Ok it works in my case. Sorry for the stupid question, but why does it work exactly? 😄

@cipolleschi
Copy link
Contributor

It's how javascript works. Our new module APIs works like classes and instances.
When you do Object.keys(nativeModule) you are asking for the methods on the instance and javascript does not provide that.
The methods and props are defined in the class (not an instance of the class) and you can get the class by asking for the prototype of an instence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p: Software Mansion Partner: Software Mansion Partner Platform: iOS iOS applications. Resolution: Answered When the issue is resolved with a simple answer Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)
Projects
None yet
Development

No branches or pull requests

5 participants