From bed487e24b90a03b282b81cee5f7d2a203963d36 Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Wed, 29 May 2024 20:34:25 -0700 Subject: [PATCH] Add BindingsInstaller for TurboModules on iOS (#44486) Summary: Add synchronous JS bindings installation for TurboModules. That would help some 3rd party JSI based modules to install JS bindings easier. Re-create from https://github.com/facebook/react-native/issues/43110 but for iOS ## Changelog: [IOS] [ADDED] - Add BindingsInstaller for TurboModules Pull Request resolved: https://github.com/facebook/react-native/pull/44486 Test Plan: Added test in RN-Tester TurboModule test case Reviewed By: javache Differential Revision: D57224891 Pulled By: philIip fbshipit-source-id: fabe5c4f8d2087ac9a465f2cb90d884b83265a68 --- .../ios/ReactCommon/RCTTurboModuleManager.mm | 14 +++++++++---- .../RCTTurboModuleWithJSIBindings.h | 20 +++++++++++++++++++ .../ios/ReactCommon/RCTSampleTurboModule.mm | 13 ++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleWithJSIBindings.h diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm index eab5e66512b..648df4b43aa 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm @@ -30,6 +30,7 @@ #import #import #import +#import #import #import #import @@ -300,7 +301,7 @@ static Class getFallbackClassFromName(const char *name) * (for now). */ -- (std::shared_ptr)provideTurboModule:(const char *)moduleName +- (std::shared_ptr)provideTurboModule:(const char *)moduleName runtime:(jsi::Runtime *)runtime { auto turboModuleLookup = _turboModuleCache.find(moduleName); if (turboModuleLookup != _turboModuleCache.end()) { @@ -404,6 +405,10 @@ static Class getFallbackClassFromName(const char *name) RCTLogError(@"TurboModule \"%@\"'s getTurboModule: method returned nil.", moduleClass); } _turboModuleCache.insert({moduleName, turboModule}); + + if ([module respondsToSelector:@selector(installJSIBindingsWithRuntime:)]) { + [(id)module installJSIBindingsWithRuntime:*runtime]; + } return turboModule; } @@ -766,7 +771,7 @@ static Class getFallbackClassFromName(const char *name) * Attach method queue to id object. * This is necessary because the id object can be eagerly created/initialized before the method * queue is required. The method queue is required for an id for JS -> Native calls. So, we need it - * before we create the id's TurboModule jsi::HostObject in provideTurboModule:. + * before we create the id's TurboModule jsi::HostObject in provideTurboModule:runtime:. */ objc_setAssociatedObject(module, &kAssociatedMethodQueueKey, methodQueue, OBJC_ASSOCIATION_RETAIN); @@ -916,7 +921,8 @@ static Class getFallbackClassFromName(const char *name) * aren't any strong references to it in ObjC. Hence, we give * __turboModuleProxy a strong reference to TurboModuleManager. */ - auto turboModuleProvider = [self](const std::string &name) -> std::shared_ptr { + auto turboModuleProvider = [self, + runtime = &runtime](const std::string &name) -> std::shared_ptr { auto moduleName = name.c_str(); TurboModulePerfLogger::moduleJSRequireBeginningStart(moduleName); @@ -930,7 +936,7 @@ static Class getFallbackClassFromName(const char *name) * Additionally, if a TurboModule with the name `name` isn't found, then we * trigger an assertion failure. */ - auto turboModule = [self provideTurboModule:moduleName]; + auto turboModule = [self provideTurboModule:moduleName runtime:runtime]; if (moduleWasNotInitialized && [self moduleIsInitialized:moduleName]) { [self->_bridge.performanceLogger markStopForTag:RCTPLTurboModuleSetup]; diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleWithJSIBindings.h b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleWithJSIBindings.h new file mode 100644 index 00000000000..44c8cfceb8b --- /dev/null +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleWithJSIBindings.h @@ -0,0 +1,20 @@ +/* + * 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 + +#ifdef __cplusplus +#include +#endif + +@protocol RCTTurboModuleWithJSIBindings + +#ifdef __cplusplus +- (void)installJSIBindingsWithRuntime:(facebook::jsi::Runtime &)runtime; +#endif + +@end diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm index 1c7b70a7f30..c7d9666a390 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm +++ b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm @@ -10,10 +10,14 @@ #import #import +#import #import using namespace facebook::react; +@interface RCTSampleTurboModule () +@end + @implementation RCTSampleTurboModule // Backward-compatible export @@ -66,6 +70,15 @@ RCT_EXPORT_MODULE() return [self getConstants]; } +#pragma mark - RCTTurboModuleWithJSIBindings + +- (void)installJSIBindingsWithRuntime:(facebook::jsi::Runtime &)runtime +{ + runtime.global().setProperty(runtime, "__SampleTurboModuleJSIBindings", "Hello JSI!"); +} + +#pragma mark - Spec Methods + RCT_EXPORT_METHOD(voidFunc) { // Nothing to do