Skip to content

Xcode 16 框架包含Bitcode导致的资产验证失败

2024年9月升级Xcode 16后触发的新问题
当使用 macOS 15 Sequoia 和 Xcode 16 进行构建时,asset validation failed invalid executable 错误意味着存在被弃用的Bitcode框架,本文提供永久解决方案

问题分析

升级到 Xcode 16 后,苹果已全面弃用 Bitcode(应用的中间编译表示形式)。但由于部分第三方框架(如 Hermes、Facebook SDK、OpenSSL 等)仍包含 Bitcode,导致在提交构建时出现以下错误:

Asset validation failed invalid executable. 
The executable 'myapp.app/frameworks/cardio.framework/cardio' contains bitcode

永久解决方案

通过 bitcode_strip 工具移除框架中的 Bitcode,推荐在 CocoaPods 的 post_install hook 中自动化处理。

1️⃣ 基础脚本配置

Podfile 文件末尾添加以下代码(位于最外层 end 前):

ruby
post_install do |installer|
  # Bitcode清除功能定义
  bitcode_strip_path = `xcrun --find bitcode_strip`.chop!
  def strip_bitcode(bitcode_strip_path, framework_relative_path)
    abs_path = File.join(Dir.pwd, framework_relative_path)
    command = "#{bitcode_strip_path} #{abs_path} -r -o #{abs_path}"
    puts "移除Bitcode: #{command}"
    system(command)
  end

  # 需要处理的框架路径列表(需替换为实际路径)
  framework_paths = [
    # 格式:"Pods/框架名/路径/可执行文件"
    "Pods/hermes-engine/destroot/Library/Frameworks/macosx/hermes.framework/hermes",
    "Pods/FBSDKCoreKit/XCFrameworks/FBSDKCoreKit.xcframework/ios-arm64/FBSDKCoreKit.framework/FBSDKCoreKit"
  ]

  # 批量处理所有框架
  framework_paths.each do |path|
    strip_bitcode(bitcode_strip_path, path)
  end
end

2️⃣ 已有 post_install 的情况

若项目中已存在 post_install ,直接插入核心功能代码:

ruby
post_install do |installer|
  ...原有代码...
  
  # 插入以下Bitcode移除代码
  bitcode_strip_path = `xcrun --find bitcode_strip`.chop!
  def strip_bitcode(bitcode_strip_path, framework_relative_path)
    abs_path = File.join(Dir.pwd, framework_relative_path)
    command = "#{bitcode_strip_path} #{abs_path} -r -o #{abs_path}"
    puts "清除Bitcode: #{command}"
    system(command)
  end

  framework_paths = [ ... ] # 路径数组
  framework_paths.each { |path| strip_bitcode(bitcode_strip_path, path) }
end

3️⃣ 执行生效命令

bash
pod install # 应用Podfile变更

如何定位框架路径

核心原则

Xcode 报错信息中的路径可直接复用,或通过终端命令查找

方法一:直接从报错信息提取

  1. 在 Xcode 构建日志中找到类似错误:
    The executable 'xxx.app/Frameworks/ProblemFramework.framework/binary' contains bitcode
  2. 提取路径核心部分并转换格式:
    xxx.app/Frameworks/ProblemFramework.framework/binary
    "Pods/ProblemFramework/.../ProblemFramework.framework/binary"

方法二:终端 find 命令检索

bash
# 在项目根目录执行(替换framework_name)
cd ios
find Pods -name "FrameworkName" 
# 示例:查找 glog 框架
# 返回:Pods/Flipper-Glog/Frameworks/glog.xcframework/.../glog.framework/glog

方法三:常见框架路径参考

ruby
framework_paths = [
  # Hermes 引擎
  "Pods/hermes-engine/destroot/Library/Frameworks/universal/hermes.xcframework/ios-arm64/hermes.framework/hermes",
  
  # Facebook SDK 系列
  "Pods/FBSDKCoreKit/XCFrameworks/FBSDKCoreKit.xcframework/ios-arm64/FBSDKCoreKit.framework/FBSDKCoreKit",
  "Pods/FBSDKLoginKit/XCFrameworks/FBSDKLoginKit.xcframework/ios-arm64/FBSDKLoginKit.framework/FBSDKLoginKit",
  
  # 常见三方库
  "Pods/OpenSSL-Universal/Frameworks/OpenSSL.xcframework/ios-arm64_armv7/OpenSSL.framework/OpenSSL",
  "Pods/MapboxCommon/MapboxCommon.xcframework/ios-arm64/MapboxCommon.framework/MapboxCommon"
]

重要提示

  1. 每个项目路径不同 - 必须根据实际错误信息或 find 结果调整路径
  2. 支持多路径配置 - 数组可包含多个框架路径
  3. 完整操作链:修改 Podfile → pod install → 重新构建

手动移除方案(适用于单次修复)

若需临时处理已生成的二进制文件:

bash
# 通用命令格式
xcrun bitcode_strip -r [完整框架路径] -o [输出路径]
# 示例(路径根据实际情况替换)
xcrun bitcode_strip -r build/ios/Release-iphoneos/AppName.app/Frameworks/Problem.framework/Problem -o build/ios/Release-iphoneos/AppName.app/Frameworks/Problem.framework/Problem

技术原理说明

  • bitcode_strip -r 命令递归删除 Mach-O 文件中的 Bitcode 段
  • 操作原理:直接修改二进制文件结构,不涉及代码重新编译
  • 安全性:苹果官方工具,不会破坏原有代码逻辑

常见问题解决

问题:找不到指定框架路径?

  • 解决方案:使用 find Pods -name "FrameworkName" 搜索实际路径
  • 技巧:在 Pods 目录中按 ⌘+Option+J 启用搜索功能

问题:Bitcode 在模拟器架构中无法移除?

  • 确保同时处理 ios-arm64ios-arm64_i386_x86_64-simulator 目录下的二进制

通过此方案处理 Bitcode 问题后,应用可正常通过 Xcode 16 的验证流程并提交至 App Store。建议长期维护框架路径列表,以便后续团队协作。