You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode 15启用ENABLE_USER_SCRIPT_SANDBOXING后构建循环问题求助

Xcode 15下CFBundleVersion构建计数器的合规解决方案

问题背景

多年来一直用以下Run Script维护Info.plist中的CFBundleVersion作为构建计数器,Swift代码中通过let bld = Bundle.main.infoDictionary?["CFBundleVersion"]读取该值:

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

升级Xcode 15后,启用ENABLE_USER_SCRIPT_SANDBOXING = YES时出现PhaseScriptExecution failed with a nonzero exit code错误,添加Info.plist作为脚本的输入/输出文件后解决了该错误,但又触发了循环依赖问题:

Cycle inside ; building could produce unreliable results. This usually can be resolved by moving the shell script phase 'Run Script' so that it runs before the build phase that depends on its outputs.

具体提示Images.xcassets依赖Info.plist,即使将Run Script移到Build Phases最顶部也无法解决。需要找到符合Xcode 15沙箱要求且安全的解决方案,同时保留原有的Swift取值逻辑。

合规解决方案

方案1:修改编译后的Info.plist副本(推荐)

核心思路是不直接修改项目源文件中的Info.plist,而是修改编译后打包进App的Info.plist副本,彻底避免源文件的依赖循环:

  1. 将Run Script阶段移到Copy Bundle Resources之后(确保编译后的Info.plist已生成)
  2. 使用以下脚本替换原有脚本:
#!/bin/bash
# 定位到编译后的Info.plist路径(已复制到构建产物目录)
APP_INFO_PLIST="${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}"

# 读取并递增build号
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$APP_INFO_PLIST")
buildNumber=$(($buildNumber + 1))

# 更新编译后的Info.plist(App包内的最终版本)
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$APP_INFO_PLIST"

# 可选:同步更新源Info.plist,保证下次构建的初始值正确
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
  1. 无需设置脚本的输入/输出文件,ENABLE_USER_SCRIPT_SANDBOXING可保持YES

方案2:改用Xcode内置变量维护版本号

利用Xcode原生的CURRENT_PROJECT_VERSION和MARKETING_VERSION机制,彻底规避Info.plist的修改操作:

  1. 在项目设置中,将CURRENT_PROJECT_VERSION设为初始构建号(比如1)
  2. 在Info.plist中,将CFBundleVersion的值改为$(CURRENT_PROJECT_VERSION)
  3. 使用以下脚本替代原有脚本,直接更新项目设置中的版本号:
#!/bin/bash
# 获取项目文件路径
PROJECT_FILE="${PROJECT_FILE_PATH}/project.pbxproj"

# 读取当前CURRENT_PROJECT_VERSION
currentVersion=$(/usr/libexec/PlistBuddy -c "Print CURRENT_PROJECT_VERSION" "$PROJECT_FILE")
currentVersion=$(($currentVersion + 1))

# 更新项目设置中的构建号
/usr/libexec/PlistBuddy -c "Set :objects:${PROJECT_OBJECT_IDENTIFIER}:CURRENT_PROJECT_VERSION $currentVersion" "$PROJECT_FILE"
  1. 将Run Script阶段移到Build之前的任意位置,无需设置输入/输出,完全符合沙箱要求

方案3:移除隐式依赖(不推荐)

若坚持修改源Info.plist,可手动编辑项目文件project.pbxproj,移除Images.xcassets对Info.plist的隐式依赖,但这种方法可能破坏Xcode的内部构建逻辑,仅作为临时应急方案使用。

内容的提问来源于stack exchange,提问作者robm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:30:28