【问题标题】:Which iOS app version/build number(s) MUST be incremented upon App Store release?哪个 iOS 应用程序版本/内部版本号必须在 App Store 发布时增加?
【发布时间】:2014-02-03 04:45:19
【问题描述】:

iOS 应用的版本/构建字段包括:

  • "Version" CFBundleShortVersionString (String - iOS, OS X) 指定包的发布版本号,它标识了应用程序的发布迭代。发布版本号是一个由三个以句点分隔的整数组成的字符串。

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

  • “iTunes Connect 版本号”:您在 iTunes Connect 上创建应用的新版本时指定的版本号。

我的问题是:

当应用的新版本上传到 iTunes Connect 和/或发布到 App Store 时,需要增加哪些版本/内部版本号?

“版本”CFBundleShortVersionString 或“内部版本”CFBundleVersion 能否在应用更新之间保持不变?

Apple 来源的加分项或 iTunesConnect 在上传无效版本/内部版本号时显示的确切错误消息。


Android / Google Play 注意:

引发此问题的讨论是,Google Play 商店中的 Android 应用程序的公共“版本”不需要需要增加,并且没有经过验证. android:versionName 可以在发布、升级、降级之间保持不变,或者是任何随机字符串,而不是看似有效的“版本号”。

android:versionName — 一个字符串值,代表应用程序代码的发布版本,应该向用户显示。

该值是一个字符串,以便您可以将应用程序版本描述为<major>.<minor>.<point> 字符串,或任何其他类型的绝对或相对版本标识符。

Difference between versionName and versionNumber in Android

而 android:versionCode 被强制为释放时递增的整数。


苹果文档

正如the newly accepted answer 中所述,Apple 最近发布了一份技术说明,详细说明了他们的版本和内部版本号方案:

Apple Technical Note TN2420 - Version Numbers and Build Numbers

【问题讨论】:

标签: ios app-store app-store-connect mac-app-store


【解决方案1】:

我正准备发布一个新的 Mac App Store 应用。使用YEAR.release (build) 的CalVer 格式。

我上传了几个版本:2020.0 (1)、2020.0 (2) 等。我最终提交了2020.0 (8) 以供 App Store 审核。已通过审核并处于等待开发者发布状态。

我想在发布之前修复一些问题,所以我在同一个发布系列中添加了一个新版本:2020.0 (9)。

这会导致错误:

App Store Connect 操作错误

ERROR ITMS-90062:“此捆绑包无效。Info.plist 文件中键 CFBundleShortVersionString [2020.0] 的值必须包含比先前批准的版本更高的版本 [ 2020.0]。有关CFBundleShortVersionString的更多信息,请访问https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"

这很烦人,因为我的2020.0 版本从未真正发布。从这个问题的公认答案中,我的印象是,在应用程序在 App Store 上可用之前,您可以继续发布具有相同版本的新版本。

如果应用状态为Pending Developer Release,则解决方案似乎是“发布火车”(相同版本+新版本)无法更新。要么发布您现有的构建,然后增加版本,要么在 App Store Connect 中取消此发布,以允许进一步上传此发布系列。

【讨论】:

  • 如果它对上下文有帮助,我在 2015 年左右开发了一个应用程序,我认为我们使用了与您相同的构建策略,并且是允许的。当我在 2018 年左右管理另一个应用程序时,我得到了你所犯的错误,所以我认为规则已经改变为你所描述的。
【解决方案2】:

我可以确认,刚刚尝试了两种方法,一系列版本和内部版本号...

1.0.0 (1)
1.0.1 (1)
1.0.2 (1)

...对于 iOS 应用程序将被接受,但对于 Mac (Catalyst) 应用程序,它会返回此错误:

错误 ITMS-90061:“此捆绑包无效。Info.plist 文件中键 CFBundleVersion [1] 的值必须包含比之前上传的版本 [2] 更高的版本。”

Mac 版本和内部版本号需要像...

1.0.0 (1)
1.0.1 (2)
1.0.2 (3)

对于 iOS,我曾经输入版本号作为版本号加上第四位数字,例如...

1.0.0 (1.0.0.1)
1.0.1 (1.0.1.1)
1.0.2 (1.0.2.1)

...但 Mac 应用程序也不允许这样做。当我尝试提交我的第一个 Mac (Catalyst) 应用程序时,Apple 只接受包含三个或更少数字的内部版本号:

错误 ITMS-9000:“此捆绑包无效。Info.plist 文件中键 CFBundleVersion [1.0.0.1] 的值必须是最多三个非负整数的句点分隔列表。”

所以我更改为单个数字,每次构建都会递增,并在版本号之间继续递增。

【讨论】:

  • 你有它给你的任何错误信息吗?如果有,请引用他们!
【解决方案3】:

Apple Technical Note TN2420, Version Numbers and Build Numbers

总结:

  • 这对(Version、Build number)必须是唯一的。
    • 序列有效:(1.0.1, 12) -> (1.0.1, 13) -> (1.0.2, 13) -> (1.0.2, 14) ...
  • Version (CFBundleShortVersionString) 必须按升序排列。
  • Build number (CFBundleVersion) 必须按升序排列。

版本号和内部版本号清单

您可以在向 App Store 提交新版本时检查以下内容。确保正确设置版本号和内部版本号将有助于避免您的应用因配置不当而被自动拒绝。

  1. 对于您的应用程序的每个新版本,您需要发明一个新的版本号。此数字应大于您使用的最后一个版本号。尽管您可以为应用的任何特定版本提供多个构建版本,但您只需为应用的每个新版本使用一个新版本号。
  2. 您不能重复使用版本号。
  3. 对于您提交的每个新版本,您都需要创建一个新版本号,其值大于您上次使用的版本号(对于同一版本)。
  4. 您可以在不同的版本序列中重复使用内部版本号,但不能在同一版本序列中重复使用内部版本号。 对于 macOS 应用,您不能在任何版本序列中重复使用内部版本号。

根据清单,以下(Version, Build Number) 序列也是有效的。

  • 案例:在不同的发布序列中重用Build Number。 (注意:不是 macOS 应用程序)

    (1.0.0, 1) -> (1.0.0, 2) -> ... -> (1.0.0, 11) -> (1.0.1, 1) -> (1.0.1, 2)

【讨论】:

  • 我很困惑。其中一个条件是“您不能重复使用版本号”,但在最后一个示例中,版本号保持不变,而内部版本号正在增加。我是不是误解了什么?
  • @Emil,我认为它的 (Version, Build Number) 对不能重复使用。
  • @EmilParikh 版本号可以在发布之前多次上传到 Apple,每个版本号都有一个唯一的内部版本号。但是一旦发布,您就不能重复使用该版本号。
  • TN2420 说“版本号和内部版本号可能最多三个组件由句点分隔”,然后提供以下非法示例 1.10000.1.5。但是看起来很多应用程序,including chrome 使用包含 4 个组件的版本号(例如 68.0.3440.83)。我想这可以通过 TN2420 页面提到“重要提示:该文档不再更新。”这一事实来解释,但是我无法找到定义新规则的更新文档.还有人困惑吗?
  • 错误地提交了两个相同的Version 和Build number 包两次。 App Connect 自动将第二次提交的Build number 增加 1。因此,我最终将 1.3 (50) 变为 1.3 (50),而第二个 1.3 (50) 变为 1.3 (51)。我没有找到任何文档,在这种特殊情况下,App Connect 会自行增加内部版本号,因此会在输入的 Xcode 版本和 App Connect 版本之间产生不匹配。这是已知/记录在案的行为吗?
【解决方案4】:

当前的Apple Technical Note TN2420, Version Numbers and Build Numbers 说(我的粗体字):

  1. 对于 iOS 应用程序,您可以在不同的发布序列中重复使用内部版本号,但您不能在同一版本序列中重复使用内部版本号。 对于 macOS 应用,您不能在任何发布序列中重复使用内部版本号。

很遗憾,这意味着当您尝试在 Mac Catalyst 上发布相同的构建时,您无法重复使用与 iOS 上的发布序列号对应的构建号。

就我而言,例如,由于一些较早的问题,我最终将 1.0.2(4) 作为 Mac Catalyst 应用程序发布,对应于 iOS 上的 1.0.2(1)。现在,当尝试在两者上发布 1.0.3(1) 时,由于内部版本号,该应用程序在 MacOS 上的验证失败,而在 iOS 上通过了验证。

我想现在我会定期在 iOS 和 MacOS 上发布相同的应用程序,我将采用与日期相对应的内部版本号,例如 20200111,如果我需要在给定范围内更改内部版本号,则以小数点递增释放。

【讨论】:

    【解决方案5】:

    CFBundleShortVersionString 是版本的公共“名称”(例如:“2.5”或“3.8.1”)。 您必须在每次发布时增加它。

    CFBundleVersion 是私有 build 编号。在 AppStore 上看不到它。您必须在每次上传时增加它。这意味着如果你在一个二进制文件上线之前拒绝它,并且你想上传一个新的二进制文件,它将有相同的 CFBundleShortVersionString 但必须有一个更高的 CFBundleVersion (例如:public "2.5", private "2.5",然后二进制拒绝,重新上传 private "2.5.1")

    2016 年 11 月 16 日编辑:

    /!\ CFBundleVersion 属性(与 CFBundleName 一起)也用于NSURLConnection 发送的 User-Agent 标头中你的代码。

    示例:如果 CFBundleName 是 MyApp 并且 CFBundleVersion 是 2.21,那么您的代码使用 NSURLConnection 直接发送的任何编程 HTTP 查询都将嵌入标题:

    User-Agent: MyApp/2.21 CFNetwork/... Darwin/...

    (这不适用于 UIWebView 自动发出的请求)。

    【讨论】:

    • 上传/发布的要求有很大区别。
    • @gabriel,我尝试将内部版本号设置为 X.X-rc2,但 Organizer 验证器不允许我设置与 X.Y.Z 不同的任何内容,其中 X、Y 和 Z 是整数 :S 。拥有 -rc2 内部版本号会很棒,您是否曾经能够使用它提交一个版本?
    • @nestor 你是对的,我错了。只允许数字。让我编辑我的答案。
    • @gabriel,我使用脚本将X.X-rc2解析为X.X.2,以便CI系统生成buildNumber上传到iTunesConnect。
    【解决方案6】:

    在向 App Store 发布新版本时,CFBundleVersion 和 CFBundleShortVersionString必须递增。

    此外,其中一个字符串必须与 iTunes Connect 中指定的版本匹配。

    This question 包含上述 Xcode Organizer 的验证器在 CFBundleVersion 和 CFBundleShortVersionString 未递增时拒绝验证应用程序的屏幕截图。

    • 此捆绑包无效。 Info.plist文件中CFBundleVersion[1.0]键的值必须包含比之前上传的版本[1.134]更高的版本。

    • 此捆绑包无效。 Info.plist文件中CFBundleShortVersionString[1.0]键的值必须包含比之前上传的版本[1.134]更高的版本。

    验证器还会引发错误,证明其中一个字符串必须与在 iTunes Connect 上创建的应用程序版本匹配。

    • 版本不匹配。 Info.plist 中的 CFBundleVersion ['1.0'] 和 CFBundleShortVersionString ['1.0'] 都与 iTunes Connect ['1.4'] 中设置的应用版本不匹配。

    【讨论】:

      【解决方案7】:

      您需要增加两者。

      上传新版本时,您需要在 iTunes Connect 上创建一个新版本,该版本会自动高于之前的版本。 iTunes Connect 上的这个版本需要一个具有相同版本号的二进制文件,因此需要增加 CFBundleShortVersionString。

      如果您更新版本但忘记增加CFBundleVersion,您将在上传过程中遇到错误。请参阅 pkamb 的答案和屏幕截图。

      CFBundleShortVersionString和CFBundleVersion详情请见:https://stackoverflow.com/a/31921249/936957

      【讨论】:

        【解决方案8】:

        CFBundleShortVersionString 应与您提供的 iTunes Connect 版本号相匹配。它也是用户在 App Store 中查看您的 App 时出现的版本号。

        版本号显示在商店中,该版本应与您稍后在 iTunes Connect 中输入的版本号相匹配。

        Source

        CFBundleVersion 不会显示在 App Store 中,但 iTunes 使用它来确定您的应用程序何时更新。

        如果您更新构建字符串,如“设置版本号和构建字符串”中所述,iTunes 会识别出构建字符串已更改并正确同步新的 iOS App Store 包以测试设备。

        Source

        更具体地回答您的问题...

        将新版本的应用上传到应用商店时,需要增加哪些版本/内部版本号?

        两者兼而有之。一个显示在 App Store 中,另一个被 iTunes 用来更新 App。

        CFBundleShortVersionString 或 CFBundleVersion 能否在应用更新之间保持不变?

        没有。 (元问题,这里的用例是什么?如果您以任何方式编辑了有效负载,构建将有所不同,用户会想知道它)。如果您尝试,您会看到如下错误消息:

        或者将它们与之前的相应数字进行比较,以确保在新版本的应用中上传的数字更大?

        是的。使用semver.org 标准。

        CFBundleShortVersionString 和 CFBundleVersion 数字是否相互比较?

        没有。

        【讨论】:

        • 对,我知道这两个数字是怎么用的。问题是:在发布应用程序的新版本时,它们是否都需要递增?
        • 是的,如果您尝试将应用推送到应用商店而不更新两者,您将看到一条错误消息,例如stackoverflow.com/questions/19367893/…
        • 谢谢,很好的编辑。特别是对于那个链接。组织者的验证器显示 CFBundleVersion 和 CFBundleShortVersionString 的“必须包含更高版本”错误。
        • +1 表示 SemVer 链接... 给定版本号 MAJOR.MINOR.PATCH,增加:当您进行不兼容的 API 更改时的主要版本,当您以向后兼容的方式添加功能时的次要版本, 和 PATCH 版本,当您进行向后兼容的错误修复时。
        • 关于这个:这里的用例是什么?如果您以任何方式编辑了有效负载,则构建会有所不同,用户会想知道它。我的用例是我的应用程序通过了 Apple 的成功审核,但之前从未在 App Store 上发布过。我发现了一个错误,我想修复它 - 不更改 CFBundleShortVersionString。这可能吗?我想拒绝我自己的应用。
        【解决方案9】:

        CFBundleVersion 和 CFBundleShortVersionString 必须大于应用的最后一个版本号。保持它们相同是一个好习惯。您应该在您的 -info.plist 中找到它们。

        当您尝试在管理器中验证应用程序时,如果其中任何一个未递增,则会引发错误。昨晚发生在我身上。

        【讨论】:

        • 我在我的问题中提到了这两个键。您在这里的答案是必须增加这两个值吗?你能更好地支持你的答案吗?
        • 是的,两者都需要递增。昨晚当我尝试在增加它们之前提交时,它抱怨两个键。
        • 感谢您提供更多信息。您应该编辑您的答案以在上传构建时添加您的体验。
        • “保持它们相同是一个好习惯” - 这不一定是真的。如果您有测试人员在您的应用程序上工作,您可能希望在应用更改时增加您的内部版本号,但保持您的版本号相同。例如,使用持续集成,您可以让它在部署到测试人员之前为您更新内部版本号。
        • @Andy 你是对的,有道理。感谢您指出用例。我只是考虑单一的开发人员/测试人员环境。
        【解决方案10】:

        据我所知,您只需要增加内部版本号CFBundleVersion。不一定需要增加短版本字符串,尽管您可能应该增加它,因为它确实告诉用户应用程序是新的。 Apple 确实表示编号应该遵循传统的软件版本约定,但是,如果您尝试重新上传已经存在的版本,iTunes Connect 可能会抱怨。

        长话短说,它可能有效,但可能无效。

        【讨论】:

        • 寻找关于哪些键必须增加的权威答案。如果CFBundleShortVersionString不需要递增,那么“相同”的面向用户的版本可以多次上传到App Store吗?
        猜你喜欢
        • 2016-07-23
        • 1970-01-01
        • 2019-08-15
        • 2012-09-23
        • 2014-07-29
        • 2021-11-06
        • 2020-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多