xcode 在所有目标中使用相同的 CFBundleVersion 和 CFBundleShortVersionString

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30441750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 07:11:56  来源:igfitidea点击:

Use same CFBundleVersion and CFBundleShortVersionString in all targets

iosxcodeversion

提问by jherran

I received the following email from Apple when I submit an app update:

我在提交应用更新时收到了来自 Apple 的以下电子邮件:

We have discovered one or more issues with your recent delivery for "Project". Your delivery was successful, but you may wish to correct the following issues in your next delivery:

CFBundleVersion Mismatch- The CFBundleVersion value '1' of extension 'Project.app/PlugIns/ProjectTodayExtension.appex' does not match the CFBundleVersion value '985' of its containing iOS application 'Project.app'.

CFBundleShortVersionString Mismatch- The CFBundleShortVersionString value '1.0' of extension 'Project.app/PlugIns/ProjectTodayExtension.appex' does not match the CFBundleShortVersionString value '2.1.6' of its containing iOS application 'Project.app'.

After you've corrected the issues, you can use Xcode or Application Loader to upload a new binary to iTunes Connect.

我们发现您最近为“项目”交付的一个或多个问题。您的交付成功,但您可能希望在下次交付时更正以下问题:

CFBundleVersion 不匹配- 扩展“Project.app/PlugIns/ProjectTodayExtension.appex”的 CFBundleVersion 值“1”与其包含的 iOS 应用程序“Project.app”的 CFBundleVersion 值“985”不匹配。

CFBundleShortVersionString 不匹配- 扩展“Project.app/PlugIns/ProjectTodayExtension.appex”的 CFBundleShortVersionString 值“1.0”与其包含的 iOS 应用程序“Project.app”的 CFBundleShortVersionString 值“2.1.6”不匹配。

更正问题后,您可以使用 Xcode 或 Application Loader 将新的二进制文件上传到 iTunes Connect。

Is there any way of use the same CFBundleVersionand CFBundleShortVersionStringin all targets to prevent this?

有没有办法在所有目标中使用相同的CFBundleVersionCFBundleShortVersionString来防止这种情况?

回答by stk

My solution is:

我的解决办法是:

For CFBundleShortVersionString:

对于CFBundleShortVersionString

  • Add a user-defined constant in your projectsettings
  • 项目设置中添加用户定义的常量

Add a user-defined constant in your **project** settings

在您的 **project** 设置中添加用户定义的常量

  • Name it $(CF_BUNDLE_SHORT_VERSION_STRING)and set it to your desired value
  • 将其命名为$(CF_BUNDLE_SHORT_VERSION_STRING)并将其设置为您想要的值

enter image description here

在此处输入图片说明

  • Set your version in your targets to $(CF_BUNDLE_SHORT_VERSION_STRING)
  • 将目标中的版本设置为$(CF_BUNDLE_SHORT_VERSION_STRING)

enter image description here

在此处输入图片说明

  • Repeat for all targets. Done!
  • 对所有目标重复此操作。完成


CFBundleVersion: you could do the same for CFBundleVersion, but somehow I wanted this value to be computed from my GIT repo commit count. I′ve done it like this:

CFBundleVersion:你可以对CFBundleVersion做同样的事情,但不知何故我希望这个值从我的 GIT 存储库提交计数中计算出来。我是这样做的:

  • Add a Pre-action to your main target. You access the shown dialog via Product > Scheme > Edit Scheme
  • 为您的主要目标添加一个 Pre-action 。您可以通过Product > Scheme > Edit Scheme访问显示的对话框

enter image description here

在此处输入图片说明

  • Add a Post-action to your main target.
  • 将 Post-action 添加到您的主要目标

enter image description here

在此处输入图片说明

  • Add a new Command Line Tool target named BundleVersionUpdateand one named BundleVersionRevert
  • 添加一个名为BundleVersionUpdate的新命令行工具目标和一个名为BundleVersionRevert

enter image description here

在此处输入图片说明

  • Navigate to your new BundleVersionUpdatetarget and add a new Run Script Build Phase
  • 导航到新的BundleVersionUpdate目标并添加新的运行脚本构建阶段

enter image description here

在此处输入图片说明

  • Paste the following
  • 粘贴以下内容
\#!/bin/sh

INFOPLIST="${SRCROOT}/MyApp/MyApp-Info.plist"
INFOPLIST_WKAPP="${SRCROOT}/MyApp-WKApp/Info.plist"
INFOPLIST_WKEXT="${SRCROOT}/MyApp-WKExt/Info.plist"

PLISTCMD="Set :CFBundleVersion $(git rev-list --all|wc -l)"

echo -n "$INFOPLIST" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"

echo -n "$INFOPLIST_WKAPP" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"

echo -n "$INFOPLIST_WKEXT" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"
\#!/bin/sh

INFOPLIST="${SRCROOT}/MyApp/MyApp-Info.plist"
INFOPLIST_WKAPP="${SRCROOT}/MyApp-WKApp/Info.plist"
INFOPLIST_WKEXT="${SRCROOT}/MyApp-WKExt/Info.plist"

PLISTCMD="Set :CFBundleVersion $(git rev-list --all|wc -l)"

echo -n "$INFOPLIST" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"

echo -n "$INFOPLIST_WKAPP" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"

echo -n "$INFOPLIST_WKEXT" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"
  • Navigate to your new BundleVersionReverttarget and add a new Run Script Build Phase and paste this:
  • 导航到新的BundleVersionRevert目标并添加新的运行脚本构建阶段并粘贴:
\#!/bin/sh

INFOPLIST="${SRCROOT}/MyApp/MyApp-Info.plist"
INFOPLIST_WKAPP="${SRCROOT}/MyApp-WKApp/Info.plist"
INFOPLIST_WKEXT="${SRCROOT}/MyApp-WKExt/Info.plist"

PLISTCMD="Set :CFBundleVersion SCRIPTED"

echo -n "$INFOPLIST" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"

echo -n "$INFOPLIST_WKAPP" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"

echo -n "$INFOPLIST_WKEXT" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"
\#!/bin/sh

INFOPLIST="${SRCROOT}/MyApp/MyApp-Info.plist"
INFOPLIST_WKAPP="${SRCROOT}/MyApp-WKApp/Info.plist"
INFOPLIST_WKEXT="${SRCROOT}/MyApp-WKExt/Info.plist"

PLISTCMD="Set :CFBundleVersion SCRIPTED"

echo -n "$INFOPLIST" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"

echo -n "$INFOPLIST_WKAPP" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"

echo -n "$INFOPLIST_WKEXT" 
| xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"
  • Enjoy!
  • 享受!

回答by Oren

The scheme actions aren't in source control so it's better to add a build phase into your app's target. Syncing the versions across all targets can be solved with a simple script that can be modified for every target you want synced:

方案操作不在源代码控制中,因此最好将构建阶段添加到应用程序的目标中。在所有目标之间同步版本可以通过一个简单的脚本来解决,该脚本可以针对您想要同步的每个目标进行修改:

  1. Add "New Run Script Phase" in "Build Phases" for your app's target
  1. 在“构建阶段”中为您的应用程序的目标添加“新运行脚本阶段

enter image description here

在此处输入图片说明

  1. Rename the script to something like "Sync Versions" and drag it above "Compile Sources" (NOTE: Xcode has a bug that may prevent the drag-drop to work. If so, you'll need to manually edit the .pbxproj file so the build phase goes in the right spot

  2. Paste the following script into the shell:

    INFOPLIST_MYAPP="${SRCROOT}/MyApp/MyApp-Info.plist"
    myAppVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_MYAPP")
    myAppBuild=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_MYAPP")
    
    INFOPLIST_SHAREEXT="${SRCROOT}/ShareExtension/Info.plist"
    /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $myAppVersion" "$INFOPLIST_SHAREEXT"
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $myAppBuild" "$INFOPLIST_SHAREEXT"
    
  1. 将脚本重命名为“同步版本”之类的内容并将其拖到“编译源”上方(注意:Xcode 有一个错误,可能会阻止拖放工作。如果是这样,您需要手动编辑 .pbxproj 文件,以便构建阶段在正确的位置进行

  2. 将以下脚本粘贴到 shell 中:

    INFOPLIST_MYAPP="${SRCROOT}/MyApp/MyApp-Info.plist"
    myAppVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_MYAPP")
    myAppBuild=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_MYAPP")
    
    INFOPLIST_SHAREEXT="${SRCROOT}/ShareExtension/Info.plist"
    /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $myAppVersion" "$INFOPLIST_SHAREEXT"
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $myAppBuild" "$INFOPLIST_SHAREEXT"
    

enter image description here

在此处输入图片说明

  1. Build your project as you normally and your share extension's version & build will stay in sync with your main target.
  1. 像往常一样构建您的项目,您的共享扩展的版本和构建将与您的主要目标保持同步。

回答by Bruno Araujo de Oliveira

The version of your ProjectTodayExtension.appex have to be the same as your app. example:

您的 ProjectTodayExtension.appex 的版本必须与您的应用程序相同。例子:

Target> General:

目标> 一般:

Version: 1.0 <- change here Biuld: 1.0

版本:1.0 <- 在此处更改 Biuld:1.0

If the version of your app to get on itunes connect is 2.3, then you must change the version of your TodayExtension to the same version 2.3.

如果您的应用程序在 iTunes Connect 上的版本是 2.3,那么您必须将 TodayExtension 的版本更改为相同的 2.3 版本。

回答by markgo2k

There is a really sweet version management system that Twitch has shared.

Twitch 分享了一个非常棒的版本管理系统。

Described in this blog post, it is somewhat similar to stk's accepted answerbut cleaner and also supports the following:

在这篇博客文章中描述,它有点类似于 stk 接受的答案,但更清晰,并且还支持以下内容:

  • Ties the build number directly (and reversibly) to the git commit before the build. Go back easily to the exact version built for use with crash report.

  • Handles version generation through a target dependency, which is easier to share across multiple targets.

  • Uses C Preprocessor on Info.plist functionality built into Xcode build settings to allow the version numbers to be substituted on the fly, with no modification of the Info.plist file.

  • 在构建之前将构建号直接(并且可逆地)绑定到 git 提交。轻松返回为与崩溃报告一起使用而构建的确切版本。

  • 通过目标依赖项处理版本生成,这更容易在多个目标之间共享。

  • 在 Xcode 构建设置中内置的 Info.plist 功能上使用 C 预处理器,以允许动态替换版本号,而无需修改 Info.plist 文件。

It is a little more complex to implement, but it's the best solution I've found, particularly if you have extensions or other targets whose versions must be kept in sync.

实现起来有点复杂,但它是我发现的最佳解决方案,特别是如果您有版本必须保持同步的扩展或其他目标。

Installation Notes:Note the blog does a great job of describing the four shell files, but doesn't really give installation or customization instructions. Here's what I did:

安装说明:请注意,该博客在描述四个 shell 文件方面做得很好,但并未真正提供安装或自定义说明。这是我所做的:

  1. Create a Versions subdirectory at the top level of your project (where the .xcodeproj lives).

  2. Download the four files indicated from the gist link at bottom left of the code samples. Move the four files into your Versions directory.

  3. Using terminal, cd to your Versions directory, then execute the cmd: chmod +x *to make the shell files executable

  4. Now follow the directions in the blog from the start to create your dependency target.

  5. You probably should customize the scripts a bit. I altered the naming and refactored to move the 4 tools to a separate tools directory that I share across projects. YMMV.

  1. 在项目的顶层(.xcodeproj 所在的位置)创建一个 Versions 子目录。

  2. 下载代码示例左下角的要点链接中指示的四个文件。将这四个文件移动到您的 Versions 目录中。

  3. 使用终端,cd 到您的 Versions 目录,然后执行 cmd:chmod +x *以使 shell 文件可执行

  4. 现在按照博客中的说明从一开始就创建您的依赖项目标。

  5. 您可能应该稍微自定义一下脚本。我更改了命名并进行了重构,以将 4 个工具移动到我跨项目共享的单独工具目录中。天啊。

回答by Ivar Rand

When trying to validate my archive I got an error message CFBundleShortVersionString missing. To fix the problem I went into Info.plist in the xml code and added CFBundleShortVersionString new version number This produced in plist format Bundle versions string, short This solve my problem

在尝试验证我的存档时,我收到一条错误消息 CFBundleShortVersionString 丢失。为了解决这个问题,我在 xml 代码中进入 Info.plist 并添加了 CFBundleShortVersionString 新版本号 这以 plist 格式生成 Bundle versions string, short 这解决了我的问题