125

这是我第一次提交 iOS 应用程序,我不希望我的应用程序被拒绝。

这是来自苹果文档:

CFBundleVersion (String - iOS, OS X) 指定包的构建版本号,它标识包的迭代(已发布或未发布)。构建版本号应该是由三个非负的、以句点分隔的整数组成的字符串,其中第一个整数大于零。该字符串应仅包含数字 (0-9) 和句点 (.) 字符。前导零会从每个整数中截断并被忽略(即 1.02.3 等价于 1.2.3)。此键不可本地化。

CFBundleShortVersionString (String - iOS, OS X) 指定包的发布版本号,它标识了应用程序的发布迭代。发布版本号是由三个以句点分隔的整数组成的字符串。第一个整数代表应用程序的主要修订,例如实现新功能或重大更改的修订。第二个整数表示实现不太突出的功能的修订。第三个整数代表维护版本。

此键的值与“CFBundleVersion”的值不同,后者标识应用程序的迭代(已发布或未发布)。可以通过将其包含在 InfoPlist.strings 文件中来本地化此键。

但这似乎有点奇怪。我对此的解释是将两个值相同,即:

CFBundleVersion: 1.0.0
CFBundleShortVersionString: 1.0.0

有人可以确认 100% 那是我应该说的吗?

4

7 回答 7

132

CFBundleShortVersionString为您提供应用程序的版本。它通常会在您每次将应用发布到 App Store 时递增。这是在应用程序的 App Store 页面的“版本”部分可见的版本。

CFBundleVersion为您提供用于开发和测试的内部版本号,即“技术”目的。最终用户很少对内部版本号感兴趣,但在开发过程中,您可能需要了解每个版本正在开发和修复的内容。这通常在内部发布的每次迭代中递增。您可以使用 Jenkins 等持续集成工具在每次构建时自动增加内部版本号。

版本号和内部版本号

这两个数字不相互依赖,但最好保持它们平行以避免混淆。请记住,一旦您的应用程序通过了 App Store 审核,无论您是否发布它,您都需要像 Phil 和 likeTheSky 所说的那样增加内部版本号。

用例:假设您有一个经过良好测试的构建,可以提交。它的版本号是1.0.0,内部版本号是1.0.0.32。提交应用后,您需要将版本更新为1.0.1并将内部版本号更新为1.0.1.0

于 2015-08-10T13:45:47.147 回答
89

可以这样想:“短版”(CFBundleShortVersionString)是公共版本号。“版本” ( CFBundleVersion) 更像是一个内部版本号,它可能比公开的“短版本”更频繁地更改。就我个人而言,我对两者都使用相同的,但很多人在每次构建时都会更新“版本”。无论哪种方式,您通常会在向 Apple 发布时更新“短版”。您更新“版本”的频率取决于您和您的需求。

于 2013-11-01T14:04:33.897 回答
19

rmaddy的回答是正确的。我再补充两点。

第三版号

请注意第三个版本号,它在 iTunesConnect 网站上作为应用程序定义的一部分指定。如果该数字与 Xcode 中的两个不同,Apple 会给您一个警告。您可以忽略警告,因为它不是显示停止器(不是“错误”)。

日期时间作为版本

此外,您不需要使用三个带标点符号的数字。这可能对某些应用程序有意义,传统上第一个数字的变化表明某种戏剧性的变化通常会影响兼容性。

对于其他应用程序,您可能只想使用ISO 8601标准格式样式 (YYYYMMDDHHMM) 的日期时间值。例如,201606070620。年-月-日-时-分的顺序呈现一个不断增加的数字,由于填充零,长度始终相同,按字母顺序排序时也是按时间顺序排列的。

我已经在 iOS 7、8 和 9 中运行的正在发布的 iOS 应用程序上成功使用了这种类型的版本号。

您甚至可以自动生成此值。在您项目的Target> Build Phases>Run Script面板中:

  1. Shell字段中指定:/bin/sh
  2. 粘贴下面的 5 行脚本。
  3. (可选)选中Show environment variables in build log复选框。
  4. 取消选中Run script only when installing复选框。

每次构建时,都会捕获UTC时区的当前日期时间。脚本中的-u标志使用 UTC 而不是您当前的默认时区。通常最适合程序员和系统管理员在 UTC 而不是本地时区中使用和思考。

#!/bin/bash
buildNumber=$(date -u "+%Y%m%d%H%M")
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $buildNumber" "$INFOPLIST_FILE"  # Version number
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"  # Build number
echo "DateTime for app version number: $buildNumber"

或者做一个混合,版本号为常规1.2.3,内部版本号为日期时间。要进行混合,只需注释掉前面CFBundleShortVersionString带有 a 的行。#

于 2014-05-04T20:12:59.273 回答
11

对我来说最明智的方案是使用版本号(即。CFBundleShortVersionString)为实际版本号,然后使用内部版本号(即。CFBundleVersion)代表提交到 App Store。因此,除非有任何问题并因此重新提交,否则此数字始终为 1。对于新版本,如果之前的版本在 TestFlight 测试或审核中出现问题,我会将其重置为 1。

内部版本号提供了一种命名您为特定版本提供的每个提交的方法。如上述定义中所述,您为应用的特定版本提供的所有构建的集合称为该版本的“发布火车”。对于 iOS 应用程序,内部版本号在每个发布系列中必须是唯一的,但它们不需要在不同的发布系列中是唯一的[我的重点]。也就是说,对于 iOS 应用程序,如果您愿意,您可以在不同的发布序列中再次使用相同的内部版本号。

来自技术说明 TN2420:版本号和内部版本号

于 2017-08-01T16:31:58.427 回答
7

我使用CFBundleVersion来指示 CFBundleShortVersionString 的内部构建。我使用试飞来为我的测试人员提交构建,因此它们之间的差异非常有用。

苹果文件说CFBundleVersion “应该是一个由3 个非负的、以句点分隔的整数组成的字符串”但实际上它可以是超过 3 个部分(如上面的答案所示)。我用它来表示我的开发版本,比如我的 CFBundleShortVersionString 是 1.0.0,我可以使用 1.0.0.11 表示 CFBundleVersion 来表示这是我发布 1.0.0 的第 11 个版本

提交到应用商店的每个 CFBundleVersion 都应该比以前大,否则你会得到ERROR ITMS-90478 : "Invalid Version. The build with version "xxx" can't import because a later version has been closed for new build submissions. 选择不同的版本号。”

CFBundleShortVersionString只能有 3 个部分,否则您将收到错误 ITMS-90060:Info.plist 文件中键 CFBundleShortVersionString 'xxx' 的值必须是最多三个非负整数的句点分隔列表。”

Basil Bourque 提到的第三个数字,即iTunesConnect上显示的版本号是事情可能变得复杂的地方。

我使用与CFBundleShortVersionString不同的 iTunesConnect 编号,因为当我第一次将我的应用程序提交到应用商店时,我们已经有很多轮内部版本。所以我使用 1.0 作为 iTunesConnect 编号,使用 5.x 作为 CFBundleShortVersionString。在应用商店的下一个版本中,我提供了一个功能来检查应用商店中是否有更新的版本,并意识到我现在遇到了麻烦,因为我只能获得 iTunesConnect 号码(使用http://itunes.apple.com/lookup?bundleId=)所以我需要在比较之前做一些计算带有 CFBundleShortVersionString 编号。

我试图通过使用 iTunesConnect 编号作为我的 CFBundleShortVersionString 来解决这个问题,但得到了错误,ERROR ITMS-90062:“此捆绑包无效。Info.plist 文件中键 CFBundleShortVersionString [xxx] 的值必须包含比该版本更高的版本先前批准的版本 [xxx]。”

因此,我建议始终使它们相同。

于 2016-05-12T05:44:09.063 回答
7

我从未在任何地方讨论过的问题是 CFBundleVersion 中每个字段的最大数量是多少?

通过将应用程序中的 CFBundleVersion 设置为 1.1.1 并查看“lsregister -dump”中版本的十六进制值,我确定第一个字段的最大值为 (2^22)-1 或 4194303,最大值第二个和第三个字段的值为 (2^21)-1 或 2097151。

3 个字段加起来为 64 位。

这对我们这些根据日期和时间使用 CFBundleVersion 的人来说是有影响的。

我将第一个字段设置为 YYYYMMDD。这总是大于允许的最大版本,并且会导致不可预知的结果,至少可以说,当启动服务决定运行哪个版本的应用程序时,当您安装了多个版本并使用类似 'open -a Appname ' 从命令行。

请广泛传播。我相信很多人都会对此感到困惑。

于 2017-01-12T13:25:06.173 回答
7

截至目前,各州的 Apple 文档CFBundleVersion[强调我的]:

标识捆绑包迭代的构建版本。

...

该键是一个机器可读的字符串,由一到三个以句点分隔的整数组成,例如 10.14.1。该字符串只能包含数字字符 (0-9) 和句点。

...

您可以包含更多整数,但系统会忽略它们。

对于CFBundleShortVersionString[强调我的]:

捆绑包的发行版或版本号。

...

此键是捆绑版本的用户可见字符串。要求的格式是三个以句点分隔的整数,例如 10.14.1。该字符串只能包含数字字符 (0-9) 和句点。

我建议只CFBundleVersion为每个构建(或 TestFlight 的每个版本)自动递增,并在您更改时将其重置为 0 CFBundleShortVersionString

您应该明确计划或设计一致的方法来更新CFBundleShortVersionString.

于 2019-05-10T15:07:21.827 回答