From 725e98629055d513deb37ffff99e9ab652d06f94 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Mon, 18 Nov 2024 02:39:02 -0800 Subject: [PATCH 1/2] [skip ci] Add `RCTDependencyProvider` protocol (#47648) Summary: React Native has a last temporal dependency on Codegen in the React-RCTAppDelegate pod. The RCTAppDelegate has the responsibility to provide various dependencies to react native, like third party components and various modules. ReactCodegen is generated when the user create the project, while React-RCTAppDelegate eists in React Native itself. This dependency means that we cannot prepare prebuilt for iOS for React Native because when we would have to create prebuilds, we would need the React Codegen, but we can't create a React codegen package that will fit all the apps, because React Codegen can contains App Specific modules and components and apps might have different dependencies. This change introduces the RCTDependencyProvider protocol to invert this dependency. ## Changelog: [iOS][Added] - Add RCTDependencyProvider protocol Differential Revision: D66074409 --- .../AppDelegate/RCTDependencyProvider.h | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 packages/react-native/Libraries/AppDelegate/RCTDependencyProvider.h diff --git a/packages/react-native/Libraries/AppDelegate/RCTDependencyProvider.h b/packages/react-native/Libraries/AppDelegate/RCTDependencyProvider.h new file mode 100644 index 000000000000..32b8415e7e4b --- /dev/null +++ b/packages/react-native/Libraries/AppDelegate/RCTDependencyProvider.h @@ -0,0 +1,26 @@ +/* + * 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 + +@protocol RCTComponentViewProtocol; + +NS_ASSUME_NONNULL_BEGIN + +@protocol RCTDependencyProvider + +- (NSArray *)imageURLLoaderClassNames; + +- (NSArray *)imageDataDecoderClassNames; + +- (NSArray *)URLRequestHandlerClassNames; + +- (NSDictionary> *)thirdPartyFabricComponents; + +@end + +NS_ASSUME_NONNULL_END From 72746a59a7deb38ed296376a053743a14e0a3a4c Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Mon, 18 Nov 2024 02:39:02 -0800 Subject: [PATCH 2/2] Use `RCTDependencyProvider` in RCTAppDelegate (#47649) Summary: ## This Change: This change uses the `RCTDependencyProvider` protocol created before, breaking the dependency between the RCTAppDelegate and codegen. ## Context React Native has a last temporal dependency on Codegen in the React-RCTAppDelegate pod. The RCTAppDelegate has the responsibility to provide various dependencies to react native, like third party components and various modules. ReactCodegen is generated when the user create the project, while React-RCTAppDelegate eists in React Native itself. This dependency means that we cannot prepare prebuilt for iOS for React Native because when we would have to create prebuilds, we would need the React Codegen, but we can't create a React codegen package that will fit all the apps, because React Codegen can contains App Specific modules and components and apps might have different dependencies. ## Changelog: [iOS][Breaking] - Use the RCTDependencyProvider in the RCTAppDelegate, breaking the dependency with Codegen Differential Revision: D66074438 --- .../Libraries/AppDelegate/RCTAppDelegate.h | 2 ++ .../Libraries/AppDelegate/RCTAppDelegate.mm | 17 +++-------------- .../Libraries/AppDelegate/RCTAppSetupUtils.h | 6 +++++- .../Libraries/AppDelegate/RCTAppSetupUtils.mm | 18 +++++------------- .../AppDelegate/React-RCTAppDelegate.podspec | 1 - 5 files changed, 15 insertions(+), 29 deletions(-) diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h index 44af9901ccfc..fa649f9f01bb 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h @@ -17,6 +17,7 @@ @protocol RCTComponentViewProtocol; @class RCTRootView; @class RCTSurfacePresenterBridgeAdapter; +@protocol RCTDependencyProvider; NS_ASSUME_NONNULL_BEGIN @@ -70,6 +71,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong, nullable) NSString *moduleName; @property (nonatomic, strong, nullable) NSDictionary *initialProps; @property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory; +@property (nonatomic, strong) id dependencyProvider; /// If `automaticallyLoadReactNativeWindow` is set to `true`, the React Native window will be loaded automatically. @property (nonatomic, assign) BOOL automaticallyLoadReactNativeWindow; diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm index 1d6e0e31eea3..47131cbf9ec6 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm @@ -19,6 +19,7 @@ #import #import "RCTAppDelegate+Protected.h" #import "RCTAppSetupUtils.h" +#import "RCTDependencyProvider.h" #if RN_DISABLE_OSS_PLUGIN_HEADER #import @@ -34,14 +35,6 @@ #endif #import -#if __has_include() -#define USE_OSS_CODEGEN 1 -#import -#else -// Meta internal system do not generate the RCTModulesConformingToProtocolsProvider.h file -#define USE_OSS_CODEGEN 0 -#endif - using namespace facebook::react; @interface RCTAppDelegate () @@ -236,18 +229,14 @@ - (Class)getModuleClassFromName:(const char *)name - (id)getModuleInstanceFromClass:(Class)moduleClass { - return RCTAppSetupDefaultModuleFromClass(moduleClass); + return RCTAppSetupDefaultModuleFromClass(moduleClass, self.dependencyProvider); } #pragma mark - RCTComponentViewFactoryComponentProvider - (NSDictionary> *)thirdPartyFabricComponents { -#if USE_OSS_CODEGEN - return [RCTThirdPartyComponentsProvider thirdPartyFabricComponents]; -#else - return @{}; -#endif + return self.dependencyProvider ? self.dependencyProvider.thirdPartyFabricComponents : @{}; } - (RCTRootViewFactory *)createRCTRootViewFactory diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.h b/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.h index 8c5776140e5a..84d6219a5995 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.h +++ b/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.h @@ -25,12 +25,16 @@ #import +@protocol RCTDependencyProvider; + // Forward declaration to decrease compilation coupling namespace facebook::react { class RuntimeScheduler; } -RCT_EXTERN id RCTAppSetupDefaultModuleFromClass(Class moduleClass); +RCT_EXTERN id RCTAppSetupDefaultModuleFromClass( + Class moduleClass, + id dependencyProvider); std::unique_ptr RCTAppSetupDefaultJsExecutorFactory( RCTBridge *bridge, diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm b/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm index 0478efc67001..e075d4d36425 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm @@ -27,13 +27,7 @@ // jsinspector-modern #import -#if __has_include() -#define USE_OSS_CODEGEN 1 -#import -#else -// Meta internal system do not generate the RCTModulesConformingToProtocolsProvider.h file -#define USE_OSS_CODEGEN 0 -#endif +#import "RCTDependencyProvider.h" void RCTAppSetupPrepareApp(UIApplication *application, BOOL turboModuleEnabled) { @@ -60,22 +54,20 @@ void RCTAppSetupPrepareApp(UIApplication *application, BOOL turboModuleEnabled) return [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties]; } -id RCTAppSetupDefaultModuleFromClass(Class moduleClass) +id RCTAppSetupDefaultModuleFromClass(Class moduleClass, id dependencyProvider) { // private block used to filter out modules depending on protocol conformance NSArray * (^extractModuleConformingToProtocol)(RCTModuleRegistry *, Protocol *) = ^NSArray *(RCTModuleRegistry *moduleRegistry, Protocol *protocol) { NSArray *classNames = @[]; -#if USE_OSS_CODEGEN if (protocol == @protocol(RCTImageURLLoader)) { - classNames = [RCTModulesConformingToProtocolsProvider imageURLLoaderClassNames]; + classNames = dependencyProvider ? dependencyProvider.imageURLLoaderClassNames : @[]; } else if (protocol == @protocol(RCTImageDataDecoder)) { - classNames = [RCTModulesConformingToProtocolsProvider imageDataDecoderClassNames]; + classNames = dependencyProvider ? dependencyProvider.imageDataDecoderClassNames : @[]; } else if (protocol == @protocol(RCTURLRequestHandler)) { - classNames = [RCTModulesConformingToProtocolsProvider URLRequestHandlerClassNames]; + classNames = dependencyProvider ? dependencyProvider.URLRequestHandlerClassNames : @[]; } -#endif NSMutableArray *modules = [NSMutableArray new]; diff --git a/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec b/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec index 729a7a0bb6a0..edaf73d1f060 100644 --- a/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec +++ b/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec @@ -76,7 +76,6 @@ Pod::Spec.new do |s| s.dependency "React-nativeconfig" s.dependency "React-RCTFBReactNativeSpec" s.dependency "React-defaultsnativemodule" - s.dependency "ReactCodegen" add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) add_dependency(s, "React-NativeModulesApple")