# Define a global platform for your project platform :ios, '16.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' project 'Runner', { 'Debug' => :debug, 'Profile' => :release, 'Release' => :release, } def flutter_root generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) unless File.exist?(generated_xcode_build_settings_path) raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" end File.foreach(generated_xcode_build_settings_path) do |line| matches = line.match(/FLUTTER_ROOT\=(.*)/) return matches[1].strip if matches end raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" end require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) flutter_ios_podfile_setup target 'Runner' do use_frameworks! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do inherit! :search_paths end end post_install do |installer| # ---- Auto patch: bridge symlink for swift_sdk_local ---- # local_plugins/chat_api/ios/chat_api/Package.swift 用 path 引用 # `../../../swift_sdk_local`。Flutter 会把 chat_api 软链进 # ios/Flutter/ephemeral/Packages/.packages/chat_api,SwiftPM 解析这条相对路径时 # 用的是软链路径,会去 ios/Flutter/ephemeral/swift_sdk_local 找包。 # 这里建一条桥接软链让它能找到 local_plugins/swift_sdk_local。 ephemeral_dir = File.expand_path('Flutter/ephemeral', __dir__) if Dir.exist?(ephemeral_dir) bridge_link = File.join(ephemeral_dir, 'swift_sdk_local') bridge_target = '../../../local_plugins/swift_sdk_local' # 已存在且指向正确就跳过;否则重建 needs_create = true if File.symlink?(bridge_link) current = File.readlink(bridge_link) needs_create = (current != bridge_target) File.delete(bridge_link) if needs_create elsif File.exist?(bridge_link) raise "[Podfile patch] #{bridge_link} 已存在但不是软链,无法替换;请手动处理" end if needs_create File.symlink(bridge_target, bridge_link) puts "[Podfile patch] Created swift_sdk_local bridge symlink: #{bridge_link} -> #{bridge_target}" end end # ---- Auto patch: bump FlutterGeneratedPluginSwiftPackage iOS platform ---- # Flutter 生成的中介包总是写死 .iOS("12.0"),与 Podfile 中的 # platform :ios, '16.0' 不一致,会报 # "requires minimum platform version 15.0/16.0 ... but this target supports 12.0"。 # 这里自动同步为 16.0。 generated_pkg = File.expand_path( 'Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage/Package.swift', __dir__) if File.exist?(generated_pkg) content = File.read(generated_pkg) new_content = content.gsub(/\.iOS\("\d+\.\d+"\)/, '.iOS("16.0")') if new_content != content File.write(generated_pkg, new_content) puts '[Podfile patch] Bumped FlutterGeneratedPluginSwiftPackage iOS platform to 16.0' end end # ---- Auto patch: comment out illegal `` imports in all Pods sources ---- # 新版 Xcode 模块校验禁止跨模块引用私有头 `` # `` 已包含全部 IPv6 定义,注释掉即可。 pods_dir = File.expand_path('Pods', __dir__) if Dir.exist?(pods_dir) patched_files = [] Dir.glob(File.join(pods_dir, '**', '*.{m,mm,h,hpp,c,cpp}')).each do |file| content = File.read(file) new_content = content.gsub( /^[ \t]*#\s*(?:import|include)\s*.*$/, '// \0 // patched: private header, covered by ' ) if new_content != content File.write(file, new_content) patched_files << file.sub(pods_dir + '/', '') end end unless patched_files.empty? puts "[Podfile patch] Commented out imports in #{patched_files.size} file(s):" patched_files.each { |f| puts " - #{f}" } end end installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) # Ensure all pods use the same iOS deployment target target.build_configurations.each do |config| config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0' config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ '$(inherited)', ## dart: PermissionGroup.microphone 'PERMISSION_MICROPHONE=1', ## dart: PermissionGroup.notification 'PERMISSION_NOTIFICATIONS=1', ## dart: PermissionGroup.calendar 'PERMISSION_EVENTS=1', ## dart: PermissionGroup.calendarFullAccess 'PERMISSION_EVENTS_FULL_ACCESS=1', 'PERMISSION_LOCATION=1', 'PERMISSION_LOCATION_WHENINUSE=0', ## dart: PermissionGroup.bluetooth 'PERMISSION_BLUETOOTH=1', ] # 禁用用户跟踪相关功能 config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'FBSDK_DISABLE_IDFA=1' # 这里原先有一段 config.build_settings.delete('NSUserTrackingUsageDescription'), # 意图是"不要用户追踪",但**完全无效**:那个 key 写在 Runner/Info.plist 里, # 不是 Xcode build setting,delete 一个不存在的设置什么也不会发生。 # 现已改为治本——Info.plist 里的 NSUserTrackingUsageDescription / SKAdNetworkItems / # NSAdvertisingAttributionReportEndpoint 都已删除,ATT 依赖也从 pubspec 移除。 # ⚠️ 删掉 plist 的 key 后必须清一次 DerivedData 与 SwiftPM 清单缓存,否则 # permission_handler 仍按缓存里的 PERMISSION_APP_TRACKING_TRANSPARENCY=1 编译, # 二进制里留着 ATTrackingManager 引用却没有用途说明 → 上传报 ITMS-90683。 end # 针对Facebook SDK禁用广告ID收集 if target.name.start_with?('FBSDKCoreKit') || target.name.start_with?('FacebookSDK') target.build_configurations.each do |config| config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)'] config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'FBSDK_DISABLE_IDFA=1' config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'FBSDK_DISABLE_AUTO_LOG_APP_EVENTS=1' end end end end