【问题标题】:Xcode project's "Build number"Xcode 项目的“内部版本号”
【发布时间】:2011-11-14 08:11:07
【问题描述】:

什么是内部版本号,它的用途是什么? 和版本号一样吗?

【问题讨论】:

标签: iphone ios xcode xcode4


【解决方案1】:

CFBundleVersion(捆绑版本) - 又名 Marketing version,将显示在您在 Appstore 上的产品页面上。

CFBundleShortVersionString(Bundle 版本字符串,短)- 捆绑包号,通常用作仅 TestFlight 用户可以看到的次要版本

以下是您如何以编程方式在Swift (4+) 中获取它们:

let buildNumber = Bundle.main.infoDictionary?[kCFBundleVersionKey as String] as? String,
let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")

我曾经在我的 shell 脚本中需要营销版本,这就是我使用 xcode build tools 获得它的方法:

xcodebuild -showBuildSettings -project ${SDK_PROJECT} | sed '1d;s/^ *//;s/"/\\"/g;s/ = \(.*\)/="\1"/;s/ = /=/;s/UID.*//' > xcodebuild-env.tmp
source xcodebuild-env.tmp

echo "${MARKETING_VERSION}"

【讨论】:

    【解决方案2】:

    这在 Xcode 6 中有效,并且仅在归档时修改 dSYM 信息字典:

    if [ "${CONFIGURATION}" = "Release" ]; then
    
    buildPlist="${SOURCE_ROOT}/${PROJECT_NAME}/${PROJECT_NAME}-Info.plist"
    
    PlistBuddy="/usr/libexec/PlistBuddy"
    
    CFBundleVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}")
    CFBundleVersion=$(($CFBundleVersion + 1))
    
    $PlistBuddy -c "Set :CFBundleVersion $CFBundleVersion" "$buildPlist"
    $PlistBuddy -c "Set :CFBundleVersion $CFBundleVersion" "$INFOPLIST_FILE"
    $PlistBuddy -c "Set :CFBundleVersion $CFBundleVersion" "${DWARF_DSYM_FOLDER_PATH}/${WRAPPER_NAME}.dSYM/Contents/Info.plist"
    fi
    

    【讨论】:

    • 一个评论就足够了;不需要一个新的答案,你所做的就是添加引号。
    • 我无法将其整齐地粘贴到评论中,当换行符被剥离时可读性较差
    • 我修改了一些其他的东西
    • 有一个更简单的方法:创建一个构建目标并使用它运行原始脚本来修改Info.plist文件。然后使正常的 Xcode 项目目标依赖于这个新的脚本目标。这将避免您试图避免的问题。这早在 Xcode 4.2 就被使用过,如果你使用 Build Phase 脚本弄乱了Info.plist,它会崩溃。 Related.
    • 这篇博文来自 2014 年,所以我怀疑它只在 Xcode 4.2 及更早版本中才有必要......
    【解决方案3】:

    这在 Xcode 6 中适用于我:

    cd ${SOURCE_ROOT}
    buildPlist=${SOURCE_ROOT}/${PROJECT_NAME}/${PROJECT_NAME}-Info.plist
    PlistBuddy="/usr/libexec/PlistBuddy"
    
    buildNumber=`git rev-list HEAD --count`
    buildNumber=$(($buildNumber + 1))
    
    $PlistBuddy -c "Set :CFBundleVersion $buildNumber" $buildPlist
    

    【讨论】:

    • 当 PROJECT_NAME 或 SOURCE_ROOT 包含空格时不起作用,请参阅我的改进答案
    • 仅在删除第一行时对我有用,并用 buildPlist=${INFOPLIST_FILE} 替换第二行
    【解决方案4】:

    内部版本号是指示应用当前状态的内部编号。它与版本号的不同之处在于它通常不是面向用户的,并且不像版本号通常那样表示任何差异/功能/升级。

    这样想:

    • Build (CFBundleVersion):构建的编号。通常,您从 1 开始,并在每次构建应用程序时增加 1。它很快允许比较哪个构建是最近的,它表示代码库的进展感。在与 QA 合作并需要确保针对正确的构建记录错误时,这些可能非常有价值。
    • 营销版本 (CFBundleShortVersionString) - 您用来表示此应用版本的面向用户的数字。通常这遵循 Major.minor 版本方案(例如 MyAwesomeApp 1.2),让用户知道哪些版本是较小的维护更新,哪些是重要的新功能。

    为了在您的项目中有效地使用它,Apple 提供了一个很棒的工具,称为 agvtool。它允许您轻松设置内部版本号和营销版本。它在编写脚本时特别有用(例如,轻松更新每个构建的构建号,甚至查询当前的构建号是什么)。它甚至可以做更多奇特的事情,比如在你更新内部版本号时为你标记你的 SVN。

    使用它:

    • 在 Xcode 中的版本控制下设置您的项目以使用“Apple Generic”。
    • 在终端
      • agvtool new-version 1(将内部版本号设置为 1)
      • agvtool new-marketing-version 1.0(将 Marketing 版本设置为 1.0)

    请参阅the man page of agvtool 了解大量信息

    【讨论】:

    • 我必须确保并且可能使用avgtool new-version 这样做的一件事是,如果您希望 agvtool 设置 CFBundleVersion(摘要选项卡中的“构建”或Info 选项卡)并且您希望它设置 CURRENT_PROJECT_VERSION,它们都必须被定义为某些东西。否则,agvtool 不会设置它们。
    【解决方案5】:

    我正在使用 Xcode 4.3.3 (4E3002) 并设法通过以下步骤使每个构建版本号 (CFBundleVersion) 自动增加:

    1. 选择菜单项产品/编辑方案... (Command+
    2. 扩展了构建阶段
    3. 选择预操作
    4. 点击加号添加“New Run Script Action”
    5. 输入“/bin/bash”作为“Shell”
    6. 在“提供构建设置”中选择一个目标
    7. 输入以下代码:

      buildPlist=$SRCROOT/$INFOPLIST_FILE
      PlistBuddy="/usr/libexec/PlistBuddy"
      
      CFBundleVersion=`$PlistBuddy -c "Print CFBundleVersion" $buildPlist`
      CFBundleVersion=$(($CFBundleVersion + 1))
      $PlistBuddy -c "Set :CFBundleVersion $CFBundleVersion" $buildPlist
      

    玩得开心!

    【讨论】:

    • 哇!!!这非常适合我的问题:自动增加 CFBundleVersion 并通过代码检索它而没有奇怪的行为...+1 非常感谢!!!
    • 在 OS X 10.8 上的 XCode 4.5 中,我发现 $SRCROOT/$INFOPLIST_FILE 不起作用,而 $INFOPLIST_FILE 可以。
    【解决方案6】:

    如果您想为 CFBuildDate 使用 DATE 字段,请使用:

    # get UTC date
    CFBuildDate=$(date -u +"%a %b %d %T GMT %Y")
    

    顺便说一句,来自 cdasher 的好建议

    【讨论】:

      【解决方案7】:

      许多人使用内部版本号来跟踪项目“构建”的总次数(仅针对小型项目进行编译,对于大型项目可能需要一些更复杂的过程)。

      内部版本号是一个绝对值,每次构建都会递增。另一方面,版本号是任意“标签”或“标记”,用作特定内部版本号的简写。

      假设您已经构建了 123 次项目,您的内部版本号是“123”,但为了简单起见,您可能决定将其称为“版本 1.0”。如果您再构建 20 次来修复错误,那么您的内部版本号是 143,但您的版本是“1.01”或“1.1”或任何您决定命名的版本。

      我还看到了将构建号基于源代码控制的项目。因此,CVS/SVN 团队可能会使用修订号作为他们的内部版本号。我还看到使用最新提交的 SHA 作为内部版本号的 git 项目(尽管一些管理工具假设内部版本号是一个增量值 - 显然在 SHA 的情况下,它不是)。

      【讨论】:

      • 您有用于将CFBundleVersion 设置为当前SVN 版本的构建阶段脚本吗?
      • 这应该是公认的答案,因为它实际上解决了 OP 的问题。
      • 同意,这是我一直在寻找的答案并回答了这个问题。
      【解决方案8】:

      此外,如果您将 CFBuildDate 作为字符串添加,并将 CFBuildNumber 作为字符串添加到 info.plist 中,则以下 shell 脚本(添加到运行脚本构建阶段 /bin/bash 时将自动更新您的构建号和日期:

          # Auto Increment Version Script
      buildPlist=${INFOPLIST_FILE}
      CFBuildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBuildNumber" $buildPlist)
      CFBuildNumber=$(($CFBuildNumber + 1))
      /usr/libexec/PlistBuddy -c "Set :CFBuildNumber $CFBuildNumber" $buildPlist
      CFBuildDate=$(date +%Y%m%d%H%M%S)
      /usr/libexec/PlistBuddy -c "Set :CFBuildDate $CFBuildDate" $buildPlist
      

      【讨论】:

      • 在 Xcode 4 上,我将 CFBuildNumber 更改为 CFBundleVersion ,因此它的编号将显示在 Targets Summary 编辑器的 Build 字段中。
      • 我将 plist 中的 CFBuildNumber 增量更改为将 CFBundleVersion 设置为 buildNum=`git log --oneline | wc -l` 以从 git 中提取构建标识符
      • @KennyWinker 更好地使用git rev-list HEAD --count
      • 确保此步骤在“构建阶段”列表中尽可能高,否则您在应用中看到的内容将不准确。
      • 另外,当我尝试使用 CFBuildDate 作为字符串时,会存储空字符串,当我将 CFBuildDate 设置为具有 Rogier 建议格式的日期时,日期会被保存,但不会被下一次构建覆盖 - 它只显示第一次构建日期 - 有没有人有相同的?
      【解决方案9】:

      内部版本号用于较小的更新(通常在开始时获得相当高的 1,并且可以在 1000 结束),例如:如果您更改了几行代码但没有更改逻辑或在更新中添加新功能。版本号用于相当大的更新,例如:您的应用程序中的新功能。然后你可以把它从 1.8 改成 2.0。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-30
        • 1970-01-01
        • 2011-01-25
        • 2015-02-17
        • 1970-01-01
        相关资源
        最近更新 更多