到目前为止的路
我的用例是:
- 我正在跨多个目标同步版本和内部版本号。
- 我正在将版本和内部版本号与目标的同步
Settigns.bundle
- 我正在从CI服务器读取和修改内部版本号。
我曾经在CI本身上将第1点和第2点作为目标构建脚本执行,而将第3点作为自定义脚本执行。
在Xcode构建设置中存储版本和构建的新方法导致脚本出现问题,因为它们不再能够有效地修改值。至少可以阅读。
不幸的是,我无法找到防止Xcode将版本和内部版本号存储到项目内部版本设置中的合法方法,但是我设法创建了一种解决方法。
事实证明,在构建或归档时,将Info.plist
使用写入的值。这意味着在构建期间将替换该值,这不允许我们在相同的构建期间对其进行修改。
我也尝试过使用xcodeproj
cli 修改项目,但是对项目的任何更改都会导致任何构建停止,因此该解决方案无法正常工作。
最终,在尝试了许多不同的方法之后,我终于设法找到了一个不违反Xcode新行为的折衷方案。
简短答案:
作为目标的预动作,脚本执行其各自的值写入到CFBundleShortVersionString
和CFBundleVersion
到目标的Info.plist
作为事实的来源,我使用Xcode构建设置读取所需目标的MARKETING_VERSION
和的值CURRENT_PROJECT_VERSION
。
这样,当您从项目设置中修改值时-在下一次构建/归档时-它们将被写入Info.plist
,从而允许您现有的脚本逻辑继续运行。
详细答案
在执行构建操作时修改资源的唯一方法是使用pre-action
脚本。如果尝试从构建脚本执行此操作-更改将不会立即生效,并且不会在构建/归档结束时出现。
为了添加一个预构建动作-进入编辑方案。
然后展开“构建”和“存档”部分。在下方Pre-action
,单击Provide build and settings from
下拉列表,然后选择要从中读取值的真相源目标。
添加以下脚本:
# 1)
cd ${PROJECT_DIR}
# 2)
exec > Pruvit-Int.prebuild.sync_project_version_and_build_with_info_plists.log 2>&1
# 3)
./sync_project_version_and_build_with_info_plists.sh $MARKETING_VERSION $CURRENT_PROJECT_VERSION
脚本行执行以下操作:
- 转到同步脚本所在的目录以执行它
- 允许在预操作期间写入日志,否则默认情况下任何输出均被静音
- 通过提供
MARKETING_VERSION
和执行同步脚本CURRENT_PROJECT_VERSION
最后一步是编写您自己的同步脚本,该脚本将读取所提供的值,MARKETING_VERSION
并读取CURRENT_PROJECT_VERSION
到相应的目标,以及您需要的其他任何时间。
就我而言,脚本如下:
#!/bin/bash
#IMPORTANT - this script must run as pre-action of each target's Build and Archive actions
version_number=$1
build_number=$2
echo "version_number is $version_number"
echo "build_number is $build_number"
#update Pruvit/Info.plist
pruvitInfoPlist="Pruvit/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $pruvitInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $pruvitInfoPlist
#update Pruvit/Settings.bundle
settingsPlist="Pruvit/Settings.bundle/Root.plist"
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version_number" $settingsPlist
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $build_number" $settingsPlist
#update BadgeCounter/Info.plist
badgeCounterInfoPlist="BadgeCounter/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $badgeCounterInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $badgeCounterInfoPlist
我在两个应用目标之间使用共享Info.plist
和共享Settings.bundle
,因此我必须更新一次。
我还使用了通知服务扩展BadgeCounter
,它必须具有完全相同的版本,并与嵌入它的目标相同。因此,我也对此进行了更新。