如何阻止 Xcode 11 将 CFBundleVersion 和 CFBundleShortVersionString 更改为 $(CURRENT_PROJECT_VERSION) 和 $(MARKETING_VERSION)? [英] How to stop Xcode 11 from changing CFBundleVersion and CFBundleShortVersionString to $(CURRENT_PROJECT_VERSION) and $(MARKETING_VERSION)?

查看:179
本文介绍了如何阻止 Xcode 11 将 CFBundleVersion 和 CFBundleShortVersionString 更改为 $(CURRENT_PROJECT_VERSION) 和 $(MARKETING_VERSION)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自版本 11 起,Xcode 将我的 CFBundleVersion 值设置为 $(CURRENT_PROJECT_VERSION) 并将我的 CFBundleShortVersionString 值设置为 $(MARKETING_VERSION) 每当我在目标设置(标签常规")中输入版本或构建值时.

Since version 11, Xcode sets my CFBundleVersion value to $(CURRENT_PROJECT_VERSION) and my CFBundleShortVersionString to value $(MARKETING_VERSION) whenever I enter Version or Build values in the target settings (tab "General").

我输入的实际版本和构建值现在存储在 project.pbxproj 文件中.我不想要或不喜欢这种行为,因为我使用 shell 脚本在构建时修改值.

The actual version and build values that I enter are now stored in the project.pbxproj file. I do not want or like this behaviour, as I use shell scripts to modify the values at buildtime.

我可以在 Info.plist 文件中手动设置正确的值,但是一旦我在目标设置中更改了版本或内部版本号,Xcode 就会再次更改 Info.plist 文件.

I can manually set the correct values in the Info.plist file, but as soon as I change Version or Build numbers in the target settings, the Info.plist file gets changed again by Xcode.

如何阻止 Xcode 11 执行此操作?

How do I stop Xcode 11 from doing this?

当我修改构建脚本以更改项目文件本身时,Xcode 会在项目文件更改后立即取消构建.

When I modify my build script to change the project file itself, Xcode will immediately cancel the build as soon as the project file is changed.

推荐答案

迄今为止的道路

我的用例是:

  1. 我正在同步多个目标的版本和构建编号.
  2. 我正在将版本和内部版本号与目标的Settigns.bundle
  3. 我正在从 CI 服务器读取和修改内部版本号.

我曾经将第 1 点和第 2 点作为目标构建脚本执行,将第 3 点作为 CI 本身的自定义脚本执行.

I used to execute point 1 and 2 as a target build script and point 3 as a custom script on the CI itself.

在 Xcode 构建设置中存储版本和构建的新方法导致脚本出现问题,因为它们不再能够有效地修改值.至少阅读是可能的.

The new way of storing the version and build within the Xcode build settings were causing issues with the scripts, because they were no longer able to effectively modify the values. At least reading was possible.

不幸的是,我无法找到阻止 Xcode 将版本和构建编号存储到项目构建设置中的合法方法,但是我设法创建了一个解决方法.

Unfortunately i was not able to discover a legit way of preventing Xcode from storing the version and build numbers into the project build settings, however i've managed to create a workaround.

事实证明,在进行构建或存档时,会使用写入在 Info.plist 中的值.这意味着该值在构建期间被替换,这不允许我们在同一构建时间内修改它.

It turns out that when a build or an archive is made, the value written in the Info.plist is used. This means that the value is substituted during build time, which does not allow us to modify it during the same build time.

我还尝试使用 xcodeproj cli 修改项目,但是对项目的任何更改都会导致任何构建停止,因此该解决方案不起作用.

I've also tried to modify the project using xcodeproj cli, however any changes to the project were causing any builds to stop, so this solution was not working.

最终,在我尝试了很多不同的方法之后,我终于找到了一个不违反 Xcode 新行为的折衷方案.

Eventually, after a lot of different approaches that i tried, i've finally managed find a compromise that was not violating the Xcode's new behavior.

作为目标预动作,执行一个脚本,将各自的值写入CFBundleShortVersionStringCFBundleVersion 到目标的Info.plist

As a target pre-action, a script is executed which writes the respective values to CFBundleShortVersionString and CFBundleVersion to the target's Info.plist

作为事实来源,我使用 Xcode 构建设置来读取所需目标的 MARKETING_VERSIONCURRENT_PROJECT_VERSION 的值.

As a source of truth, i use the Xcode build settings to read the values of MARKETING_VERSION and CURRENT_PROJECT_VERSION of the desired target.

这样,当您修改项目设置中的值时 - 在下一次构建/存档时 - 它们将被写入 Info.plist,允许任何现有的脚本逻辑继续工作.

This way, when you modify the values from the project settings - upon the next build/archive - they will be written to the Info.plist, allowing any if your existing scripting logic to continue to work.

根据构建操作修改资源的唯一方法是使用 pre-action 脚本.如果您尝试从构建脚本执行此操作 - 更改不会立即生效,也不会在构建/存档结束时出现.

The only way to modify a resource upon a build action is using a pre-action script. If you try doing it from a build script - the changes will not take effect immediately and will not be present at the end of the build/archive.

为了添加预构建操作 - 转到编辑方案.

In order to add a pre-build action - go to edit scheme.

然后展开构建和存档部分.在 Pre-action 下,点击 Provide build and settings from 下拉菜单,然后选择要从中读取值的真实来源目标.

Then expand the Build and Archive sections. Under Pre-action, click the Provide build and settings from dropdown and select the source of truth target from which you wish to read the values.

添加以下脚本:

# 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

记录行执行以下操作:

  1. 转到同步脚本所在的目录以执行它
  2. 允许在预操作期间写入日志,否则默认情况下任何输出都会静音
  3. 通过提供MARKETING_VERSIONCURRENT_PROJECT_VERSION 来执行同步脚本
  1. Go to the directory where the sync script is located in order to execute it
  2. Allows a log to be written during the pre-action, otherwise any output is silenced by default
  3. Execute the sync script by providing the MARKETING_VERSION and CURRENT_PROJECT_VERSION

最后一步是编写您自己的同步脚本,该脚本将所提供的 MARKETING_VERSIONCURRENT_PROJECT_VERSION 的值读取到相应的目标,以及您需要的任何时间.

The final step is to write your own sync script that reads the values of the provided MARKETING_VERSION and CURRENT_PROJECT_VERSION to the respective target/s and whenever else you want.

就我而言,脚本如下:

#!/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.plistSettings.bundle,所以我必须更新一次.

I use shared Info.plist and Settings.bundle between both of my app targets, so i have to update this once.

我还使用通知服务扩展 BadgeCounter,它必须具有完全相同的版本,并与其嵌入的目标构建.所以我也更新了.

Also i use a notification service extension BadgeCounter, which has to have the exact same version and build as the target into which it is embedded. So i update this as well.

这篇关于如何阻止 Xcode 11 将 CFBundleVersion 和 CFBundleShortVersionString 更改为 $(CURRENT_PROJECT_VERSION) 和 $(MARKETING_VERSION)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆