如何在现代Xcode项目中用fastlane同时升级双版本?
现代Xcode项目同时升级营销版本与Bundle版本的最佳实践
问题背景
在现代Xcode项目中,已不再包含完整的.plist文件,此前依赖的fastlane lane increment_version_number同时升级营销版本(CFBundleShortVersionString)和Bundle版本(CFBundleVersion)的方法已失效。尝试过如increment_version_number_in_xcodeproj这类新版lane,但这类方法会多次编译项目,对大型应用并不友好。其他fastlane插件或shell脚本也无法正常工作。
最佳实践方案
1. 直接修改Xcode项目文件(.xcodeproj)
Xcode的版本配置实际存储在项目文件的project.pbxproj中,无需编译项目,直接通过脚本修改该文件即可:
- 用Ruby脚本(契合fastlane的Ruby环境)定位并修改
MARKETING_VERSION(对应营销版本)和CURRENT_PROJECT_VERSION(对应Bundle版本)字段:
# 获取项目路径 project_path = "./YourProject.xcodeproj" project = Xcodeproj::Project.open(project_path) # 遍历所有目标,修改版本号 project.targets.each do |target| # 修改营销版本与Bundle版本 target.build_configurations.each do |config| config.build_settings['MARKETING_VERSION'] = "1.2.3" # 替换为目标营销版本 config.build_settings['CURRENT_PROJECT_VERSION'] = "456" # 替换为目标Bundle版本 end end # 保存修改 project.save
将这段脚本集成到fastlane lane中,无需编译,直接修改项目配置,速度极快,适合大型项目。
2. 使用fastlane内置操作修改项目配置
借助fastlane的xcodeproj内置能力,直接操作项目文件,无需额外第三方插件:
lane :bump_versions do xcodeproj = Xcodeproj::Project.open("./YourProject.xcodeproj") target = xcodeproj.targets.find { |t| t.name == "YourTargetName" } # 递增营销版本(示例:从1.2.2升级到1.2.3) current_marketing = target.build_configurations.first.build_settings['MARKETING_VERSION'] new_marketing = increment_version(current_marketing, bump_type: "patch") # 递增Bundle版本(示例:从455升级到456) current_bundle = target.build_configurations.first.build_settings['CURRENT_PROJECT_VERSION'] new_bundle = (current_bundle.to_i + 1).to_s # 将修改应用到所有配置 target.build_configurations.each do |config| config.build_settings['MARKETING_VERSION'] = new_marketing config.build_settings['CURRENT_PROJECT_VERSION'] = new_bundle end xcodeproj.save end
这种方法完全在fastlane环境内完成,无额外编译步骤,效率和稳定性拉满。
3. 命令行脚本直接修改(适合CI/CD场景)
如果偏好shell脚本,可使用sed直接修改project.pbxproj文件(注意确保项目配置规范,无重复配置行):
# 设置目标版本 NEW_MARKETING_VERSION="1.2.3" NEW_BUNDLE_VERSION="456" PROJECT_FILE="./YourProject.xcodeproj/project.pbxproj" # 修改营销版本 sed -i.bak "s/MARKETING_VERSION = [0-9.]*;/MARKETING_VERSION = $NEW_MARKETING_VERSION;/" "$PROJECT_FILE" # 修改Bundle版本 sed -i.bak "s/CURRENT_PROJECT_VERSION = [0-9]*;/CURRENT_PROJECT_VERSION = $NEW_BUNDLE_VERSION;/" "$PROJECT_FILE" # 删除备份文件 rm "$PROJECT_FILE.bak"
关键注意事项
- 修改前建议提交代码或备份项目文件,避免版本配置混乱。
- 确保所有Target的版本配置都被同步修改,避免部分目标版本不一致。
- 大型项目优先选择Ruby脚本或fastlane内置操作,稳定性和可读性更强。
内容的提问来源于stack exchange,提问作者Tobonaut
相关产品推荐
相关产品推荐

