require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") require 'json' podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} def ccache_enabled?(podfile_properties) # Environment variable takes precedence return ENV['USE_CCACHE'] == '1' if ENV['USE_CCACHE'] # Fall back to Podfile properties podfile_properties['apple.ccacheEnabled'] == 'true' end ENV['RCT_NEW_ARCH_ENABLED'] ||= '0' if podfile_properties['newArchEnabled'] == 'false' ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] ||= podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR'] ENV['RCT_USE_RN_DEP'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false' ENV['RCT_USE_PREBUILT_RNCORE'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false' platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1' prepare_react_native_project! target 'client' do use_expo_modules! if ENV['EXPO_USE_COMMUNITY_AUTOLINKING'] == '1' config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"]; else config_command = [ 'node', '--no-warnings', '--eval', 'require(\'expo/bin/autolinking\')', 'expo-modules-autolinking', 'react-native-config', '--json', '--platform', 'ios' ] end config = use_native_modules!(config_command) use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks'] use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS'] use_react_native!( :path => config[:reactNativePath], :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes', # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/..", :privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false', ) post_install do |installer| react_native_post_install( installer, config[:reactNativePath], :mac_catalyst_enabled => false, :ccache_enabled => ccache_enabled?(podfile_properties), ) # 生成并随归档产物携带 dSYM(用于崩溃符号化与 Upload Symbols Failed 修复) installer.pods_project.targets.each do |target| target.build_configurations.each do |build_config| build_config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf-with-dsym' build_config.build_settings['DWARF_DSYM_FILE_SHOULD_ACCOMPANY_PRODUCT'] = 'YES' end end # 修复:Xcode 编译阶段找不到 Expo 相关 modulemap # 现象:PrecompileSwiftBridgingHeader 报错 module map file '.../Build/Products/.../Expo/Expo.modulemap' not found # 原因:Pods-client 的 xcconfig 把 -fmodule-map-file 指向了 ${PODS_CONFIGURATION_BUILD_DIR},但该文件在构建早期并不存在。 # 方案:将这些 modulemap 路径改为 Pods 内稳定存在的 Target Support Files 路径。 def patch_pods_client_xcconfig!(path) return unless File.exist?(path) s = File.read(path) # expo-dev-* 的 modulemap 文件名与 module 名不同,需要单独映射 s = s.gsub('${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-launcher/EXDevLauncher.modulemap', '${PODS_ROOT}/Target Support Files/expo-dev-launcher/expo-dev-launcher.modulemap') s = s.gsub('${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-menu/EXDevMenu.modulemap', '${PODS_ROOT}/Target Support Files/expo-dev-menu/expo-dev-menu.modulemap') s = s.gsub('${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-menu-interface/EXDevMenuInterface.modulemap', '${PODS_ROOT}/Target Support Files/expo-dev-menu-interface/expo-dev-menu-interface.modulemap') # 通用映射:${PODS_CONFIGURATION_BUILD_DIR}//.modulemap -> ${PODS_ROOT}/Target Support Files//.modulemap s = s.gsub(/\$\{PODS_CONFIGURATION_BUILD_DIR\}\/([^\/]+)\/\1\.modulemap/, '${PODS_ROOT}/Target Support Files/\1/\1.modulemap') File.write(path, s) end support_dir = File.join(__dir__, 'Pods', 'Target Support Files', 'Pods-client') patch_pods_client_xcconfig!(File.join(support_dir, 'Pods-client.debug.xcconfig')) patch_pods_client_xcconfig!(File.join(support_dir, 'Pods-client.release.xcconfig')) # 修复:缺失 [CP] Copy XCFrameworks 阶段时,React/Expo 的 XCFramework 中间产物不会生成, # 导致 Swift 报 no such module 'React' 等。 # 方案:在 [CP] Embed Pods Frameworks 脚本中,先执行各个 *-xcframeworks.sh 生成中间产物。 def patch_pods_client_frameworks_sh!(path) return unless File.exist?(path) s = File.read(path) marker = "# [Mindfulness Fix] Prepare XCFramework intermediates\n" return if s.include?(marker) insert = marker + "if [ -r \"${PODS_ROOT}/Target Support Files/React-Core-prebuilt/React-Core-prebuilt-xcframeworks.sh\" ]; then\n" \ " /bin/sh \"${PODS_ROOT}/Target Support Files/React-Core-prebuilt/React-Core-prebuilt-xcframeworks.sh\"\n" \ "fi\n" \ "if [ -r \"${PODS_ROOT}/Target Support Files/ReactNativeDependencies/ReactNativeDependencies-xcframeworks.sh\" ]; then\n" \ " /bin/sh \"${PODS_ROOT}/Target Support Files/ReactNativeDependencies/ReactNativeDependencies-xcframeworks.sh\"\n" \ "fi\n" \ "if [ -r \"${PODS_ROOT}/Target Support Files/hermes-engine/hermes-engine-xcframeworks.sh\" ]; then\n" \ " /bin/sh \"${PODS_ROOT}/Target Support Files/hermes-engine/hermes-engine-xcframeworks.sh\"\n" \ "fi\n\n" s = s.sub(/^if \[\[ \"\$CONFIGURATION\" == \"Debug\" \]\]; then\n/, insert + "if [[ \"$CONFIGURATION\" == \"Debug\" ]]; then\n") File.write(path, s) end patch_pods_client_frameworks_sh!(File.join(support_dir, 'Pods-client-frameworks.sh')) # 让 React/ReactNativeDependencies/hermes 的 XCFramework 切片在编译 Swift 之前就准备好, # 否则会在 AppDelegate.swift 的 `import React` 阶段报 no such module。 def patch_expo_configure_project_sh!(path) return unless File.exist?(path) s = File.read(path) marker = "# [Mindfulness Fix] Prepare XCFramework intermediates (before Swift compile)\n" return if s.include?(marker) insert = marker + "if [ -r \"${PODS_ROOT}/Target Support Files/React-Core-prebuilt/React-Core-prebuilt-xcframeworks.sh\" ]; then\n" \ " /bin/sh \"${PODS_ROOT}/Target Support Files/React-Core-prebuilt/React-Core-prebuilt-xcframeworks.sh\"\n" \ "fi\n" \ "if [ -r \"${PODS_ROOT}/Target Support Files/ReactNativeDependencies/ReactNativeDependencies-xcframeworks.sh\" ]; then\n" \ " /bin/sh \"${PODS_ROOT}/Target Support Files/ReactNativeDependencies/ReactNativeDependencies-xcframeworks.sh\"\n" \ "fi\n" \ "if [ -r \"${PODS_ROOT}/Target Support Files/hermes-engine/hermes-engine-xcframeworks.sh\" ]; then\n" \ " /bin/sh \"${PODS_ROOT}/Target Support Files/hermes-engine/hermes-engine-xcframeworks.sh\"\n" \ "fi\n\n" # 插在首次调用 with_node 之前即可(不能用 ^,因为 with_node 不在文件开头) s = s.sub("with_node \\\n", insert + "with_node \\\n") File.write(path, s) end patch_expo_configure_project_sh!(File.join(support_dir, 'expo-configure-project.sh')) end end