From db5413865ea1841ce48b9109181f18e1386e8905 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Wed, 20 Nov 2024 09:01:01 -0800 Subject: [PATCH] Extract RCTAppDependencyProvider in a separate pod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: When breaking the last dependency, we created the `RCTApDependencyProvider` in the Codegen pod. This is not an issue per sè. The problem comes in with the new template in Swift: ReactCodegen contains some headers with some C++ code that Swift can't really process. That's why most libraries started failing in jobs like [this one](https://github.com/facebook/react-native/actions/runs/11906196751/job/33177904733): the template app was not able to load the `ReactCodegen` pod in the Swift app delegate. Given that the app delegate only have to actually load the RCTAppDependencyProvider, I extracted that class in its own pod: ReactAppDependencyProvider. The name of the pod does not follow the React-RCTXXX structure because that will create issues with the import statements and the `use_frameworks!` use case. > [!NOTE] > We need to update the template and change the `import ReactCodegen` to `import ReactAppDependencyProvider` ## Changelog: [iOS][Added] - Extract RCTAppDependencyProvider in the ReactAppDependencyProvider pod Differential Revision: D66241941 --- .../helloworld/ios/HelloWorld/AppDelegate.mm | 2 +- .../scripts/cocoapods/codegen_utils.rb | 1 + .../codegen/generate-artifacts-executor.js | 20 +++++++++++ .../RCTAppDependencyProviderMM.template | 4 +-- ...eactAppDependencyProvider.podspec.template | 34 +++++++++++++++++++ .../react-native/scripts/react_native_pods.rb | 1 + packages/rn-tester/RNTester/AppDelegate.mm | 6 ++-- 7 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 packages/react-native/scripts/codegen/templates/ReactAppDependencyProvider.podspec.template diff --git a/packages/helloworld/ios/HelloWorld/AppDelegate.mm b/packages/helloworld/ios/HelloWorld/AppDelegate.mm index 8ef5d021126f..163ec97da1da 100644 --- a/packages/helloworld/ios/HelloWorld/AppDelegate.mm +++ b/packages/helloworld/ios/HelloWorld/AppDelegate.mm @@ -8,7 +8,7 @@ #import "AppDelegate.h" #import -#import +#import @implementation AppDelegate diff --git a/packages/react-native/scripts/cocoapods/codegen_utils.rb b/packages/react-native/scripts/cocoapods/codegen_utils.rb index 76a1fc8586a2..d71c02e40eb8 100644 --- a/packages/react-native/scripts/cocoapods/codegen_utils.rb +++ b/packages/react-native/scripts/cocoapods/codegen_utils.rb @@ -119,6 +119,7 @@ def get_react_codegen_spec(package_json_file, folly_version: get_folly_config()[ 'header_mappings_dir' => './', 'platforms' => min_supported_versions, 'source_files' => "**/*.{h,mm,cpp}", + 'exclude_files' => "RCTAppDependencyProvider.{h,mm}", # these files are generated in the same codegen path but needs to belong to a different pod 'pod_target_xcconfig' => { "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), "FRAMEWORK_SEARCH_PATHS" => framework_search_paths, diff --git a/packages/react-native/scripts/codegen/generate-artifacts-executor.js b/packages/react-native/scripts/codegen/generate-artifacts-executor.js index 26d8cabc0683..c1fc5aeaf994 100644 --- a/packages/react-native/scripts/codegen/generate-artifacts-executor.js +++ b/packages/react-native/scripts/codegen/generate-artifacts-executor.js @@ -118,6 +118,14 @@ const APP_DEPENDENCY_PROVIDER_MM_TEMPLATE_PATH = path.join( 'RCTAppDependencyProviderMM.template', ); +const APP_DEPENDENCY_PROVIDER_PODSPEC_TEMPLATE_PATH = path.join( + REACT_NATIVE_PACKAGE_ROOT_FOLDER, + 'scripts', + 'codegen', + 'templates', + 'ReactAppDependencyProvider.podspec.template', +); + const codegenLog = (text, info = false) => { // ANSI escape codes for colors and formatting const reset = '\x1b[0m'; @@ -663,6 +671,18 @@ function generateAppDependencyProvider(outputDir) { const finalPathMM = path.join(outputDir, 'RCTAppDependencyProvider.mm'); fs.writeFileSync(finalPathMM, templateMM); codegenLog(`Generated artifact: ${finalPathMM}`); + + // Generate the podspec file + const templatePodspec = fs + .readFileSync(APP_DEPENDENCY_PROVIDER_PODSPEC_TEMPLATE_PATH, 'utf8') + .replace(/{react-native-version}/, packageJson.version) + .replace(/{react-native-licence}/, packageJson.license); + const finalPathPodspec = path.join( + outputDir, + 'ReactAppDependencyProvider.podspec', + ); + fs.writeFileSync(finalPathPodspec, templatePodspec); + codegenLog(`Generated podspec: ${finalPathPodspec}`); } function generateRCTThirdPartyComponents(libraries, outputDir) { diff --git a/packages/react-native/scripts/codegen/templates/RCTAppDependencyProviderMM.template b/packages/react-native/scripts/codegen/templates/RCTAppDependencyProviderMM.template index 532d7b4b4ce5..61594479cc7d 100644 --- a/packages/react-native/scripts/codegen/templates/RCTAppDependencyProviderMM.template +++ b/packages/react-native/scripts/codegen/templates/RCTAppDependencyProviderMM.template @@ -6,8 +6,8 @@ */ #import "RCTAppDependencyProvider.h" -#import "RCTModulesConformingToProtocolsProvider.h" -#import "RCTThirdPartyComponentsProvider.h" +#import +#import @implementation RCTAppDependencyProvider { NSArray * _URLRequestHandlerClassNames; diff --git a/packages/react-native/scripts/codegen/templates/ReactAppDependencyProvider.podspec.template b/packages/react-native/scripts/codegen/templates/ReactAppDependencyProvider.podspec.template new file mode 100644 index 000000000000..327bc9c102e3 --- /dev/null +++ b/packages/react-native/scripts/codegen/templates/ReactAppDependencyProvider.podspec.template @@ -0,0 +1,34 @@ +# 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. + +version = "{react-native-version}" +source = { :git => 'https://github.com/facebook/react-native.git' } +if version == '1000.0.0' + # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in. + source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1") +else + source[:tag] = "v#{version}" +end + +Pod::Spec.new do |s| + s.name = "ReactAppDependencyProvider" + s.version = version + s.summary = "The third party dependency provider for the app" + s.homepage = "https://reactnative.dev/" + s.documentation_url = "https://reactnative.dev/" + s.license = "{react-native-licence}" + s.author = "Meta Platforms, Inc. and its affiliates" + s.platforms = min_supported_versions + s.source = source + s.source_files = "**/RCTAppDependencyProvider.{h,mm}" + + # This guard prevent to install the dependencies when we run `pod install` in the old architecture. + s.pod_target_xcconfig = { + "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), + "DEFINES_MODULE" => "YES" + } + + s.dependency "ReactCodegen" +end diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb index 7d99f2b9e7d3..bc9cc30fb195 100644 --- a/packages/react-native/scripts/react_native_pods.rb +++ b/packages/react-native/scripts/react_native_pods.rb @@ -176,6 +176,7 @@ def use_react_native! ( ) pod 'ReactCodegen', :path => $CODEGEN_OUTPUT_DIR, :modular_headers => true + pod 'ReactAppDependencyProvider', :path => $CODEGEN_OUTPUT_DIR, :modular_headers => true # Always need fabric to access the RCTSurfacePresenterBridgeAdapter which allow to enable the RuntimeScheduler # If the New Arch is turned off, we will use the Old Renderer, though. diff --git a/packages/rn-tester/RNTester/AppDelegate.mm b/packages/rn-tester/RNTester/AppDelegate.mm index b862effbfcd2..64c5d4122e7d 100644 --- a/packages/rn-tester/RNTester/AppDelegate.mm +++ b/packages/rn-tester/RNTester/AppDelegate.mm @@ -24,9 +24,9 @@ #import #endif -#if __has_include() +#if __has_include() #define USE_OSS_CODEGEN 1 -#import +#import #else #define USE_OSS_CODEGEN 0 #endif @@ -41,7 +41,7 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.moduleName = @"RNTesterApp"; -#if USE_ODD_CODEGEN +#if USE_OSS_CODEGEN self.dependencyProvider = [RCTAppDependencyProvider new]; #endif // You can add your custom initial props in the dictionary below.