Xcode中的版本与构建

chr*_*ris 649 xcode ios

我有一个使用Xcode 3开发的应用程序,最近开始使用Xcode 4编辑.在目标摘要中,我有iOS应用程序目标表单,其中包含字段:标识符,版本,构建,设备和部署目标.版本字段为空白,构建字段为3.4.0(与我使用Xcode 3编辑时的应用程序版本相匹配).

我的问题是:

  1. 版本和构建字段有什么区别?

  2. 升级到Xcode 4后,为什么版本字段为空?

nek*_*kno 1212

苹果有点重新安排/重新利用这些领域.

接下来,如果您查看Application Target的Info选项卡,您应该使用"Bundle versions string,short"作为您的版本(例如,3.4.0)和"Bundle version"作为您的Build(例如,500或1A500) ).如果您没有看到它们,则可以添加它们.这些将映射到"摘要"选项卡上的正确版本和构建文本框; 它们是相同的价值观.

查看"信息"选项卡时,如果右键单击并选择" 显示原始键/值",您将看到实际名称为CFBundleShortVersionString(版本)和CFBundleVersion(构建).

版本通常用于你似乎如何使用它与Xcode 3.我不确定你在什么级别询问版本/构建差异,所以我会在哲学上回答它.

有各种各样的方案,但一个流行的方案是:

{MajorVersion}.{MinorVersion}.{}修订

  • 主要版本 - 主要更改,重新设计和功能更改
  • 次要版本 - 次要改进,功能增加
  • 修订版 - 修复错误的修补程序编号

然后单独使用Build来指示发行版或整个产品生命周期的构建总数.

许多开发人员在0时开始构建编号,每次构建时他们将数量增加一个,永远增加.在我的项目中,我有一个脚本,每次构建时都会自动增加内部版本号.请参阅以下说明.

  • 版本1.0.0可能是构建542.它需要542个版本才能达到1.0.0版本.
  • 版本1.0.1可能是构建578.
  • 版本1.1.0可能是build 694.
  • 版本2.0.0可能是构建949.

其他开发人员,包括Apple,都有一个Build版本号,包括主要版本+次要版本+版本号.这些是实际的软件版本号,而不是用于营销的值.

如果您转到Xcode菜单> 关于Xcode,您将看到版本号和构建号.如果你点击更多信息...按钮,你会看到一堆不同的版本.由于Xcode 5中删除了更多信息...按钮,此信息也可以从系统信息应用程序的软件>开发人员部分获得,可通过打开Apple菜单> 关于本机 > 系统报告...获得.

例如,Xcode 4.2(4C139).营销版本4.2是构建主要版本4,构建次要版本C和构建号码139.下一个版本(可能是4.3)可能是构建版本4D,并且构建号码将从0开始并从那里开始增量.

iPhone模拟器版本/内部版本号与iPhone,Mac等相同.

  • 3.2:(7W367a)
  • 4.0:(8A400)
  • 4.1:(8B117)
  • 4.2:(8C134)
  • 4.3:(8H7)

更新:根据请求,以下是创建脚本的步骤,该脚本在每次在Xcode中构建应用程序时运行,以读取内部版本号,增加它并将其写回应用程序的{App}-Info.plist文件.如果要将版本/内部版本号写入Settings.bundle/Root*.plist文件,可以使用可选的附加步骤.

这是从这里的方法文章扩展而来的.

在Xcode 4.2 - 5.0中:

  1. 加载您的Xcode项目.
  2. 在左侧窗格中,单击层次结构最顶部的项目.这将加载项目设置编辑器.
  3. 在中心窗格的左侧,单击TARGETS标题下的应用程序.您需要为每个项目目标配置此设置.
  4. 选择Build Phases选项卡.
    • 在Xcode 4的右下角,单击Add Build Phase按钮并选择Add Run Script.
    • 在Xcode 5中,选择Editor菜单> Add Build Phase > Add Run Script Build Phase.
  5. 拖放新的"运行脚本"阶段,将其移至" 复制包资源"阶段之前(当app-info.plist文件与您的应用程序捆绑在一起时).
  6. 在新的Run Script阶段,设置Shell : /bin/bash.
  7. 将以下内容复制并粘贴到整数构建号的脚本区域中:

    buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
    buildNumber=$(($buildNumber + 1))
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
    
    Run Code Online (Sandbox Code Playgroud)

    正如@Bdebeez指出的那样,Apple Generic Versioning Tool(agvtool)也可用.如果您更喜欢使用它,那么首先要改变一些事情:

    • 选择" 构建设置"选项卡.
    • Versioning部分下,将Current Project Version设置为您要使用的初始构建号,例如1.
    • 返回Build Phases选项卡,在Copy Bundle Resources阶段之后拖放Run Script阶段,以避免在尝试构建和更新包含您的内部版本号的源文件时出现竞争情况.

    请注意,使用该agvtool方法,您仍可以定期获取失败/取消的版本,而不会出现错误.因此,我不建议使用agvtool此脚本.

    但是,在"运行脚本"阶段,您可以使用以下脚本:

    "${DEVELOPER_BIN_DIR}/agvtool" next-version -all
    
    Run Code Online (Sandbox Code Playgroud)

    next-version参数递增版本号(bump也是同样的事情的别名),并-all更新Info.plist与新的版本号.

  8. 如果您有一个显示版本和构建的设置包,则可以在脚本末尾添加以下内容以更新版本和构建.注意:更改PreferenceSpecifiers值以匹配您的设置.PreferenceSpecifiers:2意味着查看PreferenceSpecifiersplist文件中数组下索引2处的项,因此对于基于0的索引,这是数组中的第三个首选项设置.

    productVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_FILE")
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root.plist
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root.plist
    
    Run Code Online (Sandbox Code Playgroud)

    如果您正在使用agvtool而不是Info.plist直接阅读,则可以将以下内容添加到脚本中:

    buildNumber=$("${DEVELOPER_BIN_DIR}/agvtool" what-version -terse)
    productVersion=$("${DEVELOPER_BIN_DIR}/agvtool" what-marketing-version -terse1)
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root.plist
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root.plist
    
    Run Code Online (Sandbox Code Playgroud)
  9. 如果你有一个适用于iPad和iPhone的通用应用程序,那么你也可以设置iPhone文件的设置:

    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root~iphone.plist    
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root~iphone.plist
    
    Run Code Online (Sandbox Code Playgroud)

  • "在我的项目中,我有一个脚本,每次构建时都会自动增加内部版本号" - 你能分享一下这样做吗?感谢细节anwers和原始问题. (17认同)
  • 要增加十六进制数,你可以使用`buildNumber = $(/ usr/libexec/PlistBuddy -c"打印CFBundleVersion""$ INFOPLIST_FILE")dec = $((0x $ buildNumber))buildNumber = $(($ dec + 1) )hex = $(printf"%X"$ buildNumber)/ usr/libexec/PlistBuddy -c"Set:CFBundleVersion $ hex""$ INFOPLIST_FILE"` (9认同)
  • 简而言之:AppStore中不允许使用HEX. (8认同)
  • (Xcode 5用户)您可能需要将步骤5更改为:"从菜单栏中选择编辑器 - >添加构建阶段 - >添加运行脚本构建阶段" (3认同)
  • @Andrews - 我用构建脚本的详细信息更新了我的答案. (2认同)
  • 提示:如果选中脚本“仅在安装时运行脚本”框,则仅当生成归档文件时,buildVersion才会增加。 (2认同)
  • 有关创建脚本的操作方法帖子的更新链接:https://davedelong.com/blog/2015/02/08/incrementing-build-numbers-in-xcode/ (2认同)

Dan*_*ark 71

(这里留下我自己的参考.)这将显示您在Xcode目标中看到的"版本"和"构建"字段的版本和构建:

- (NSString*) version {
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    return [NSString stringWithFormat:@"%@ build %@", version, build];
}
Run Code Online (Sandbox Code Playgroud)

在斯威夫特

func version() -> String {
    let dictionary = NSBundle.mainBundle().infoDictionary!
    let version = dictionary["CFBundleShortVersionString"] as? String
    let build = dictionary["CFBundleVersion"] as? String
    return "\(version) build \(build)"
}
Run Code Online (Sandbox Code Playgroud)

  • OT:你的方法有漏洞 - 你在`alloc` /`init`字符串,它保留了字符串,但你没有释放它.在从方法返回的对象上,通常应该使用方便方法,以便自动释放字符串,或调用`autorelease`.要么:`return [NSString stringWithFormat:@"%@ build%@",version,build];`或`return [[[NSString alloc] initWithFormat:@"%@ build%@",version,build] autorelease]; ` (2认同)
  • 在可用的常量(例如kCFBundleVersionKey)中使用常量可能更好,以避免拼写错误.虽然,我找不到一个"CFBundleShortVersionString":) (2认同)

Bde*_*eez 51

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

可以这样想:

  • Build(CFBundleVersion):构建的编号.通常,您从1开始,并在应用程序的每个版本中增加1.它可以快速比较哪个版本更新,并且它代表了代码库的进步感.在使用QA并且需要确保针对正确的构建记录错误时,这些可能是非常有价值的.
  • 营销版本(CFBundleShortVersionString):用于表示此版本应用的面向用户的号码.通常,这遵循Major.minor版本方案(例如MyAwesomeApp 1.2),以便让用户知道哪些版本是较小的维护更新,哪些是大量新功能.

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

要使用它:

  • 在版本控制下的Xcode中设置项目,以使用"Apple Generic".
  • 在终端
    • agvtool new-version 1 (将Build编号设置为1)
    • agvtool new-marketing-version 1.0 (将营销版本设置为1.0)

请参阅手册页以agvtool获取大量信息


ale*_*e84 25

如果构建号是一个浮点值,在上面的答案中自动增加内部版本号的脚本对我来说不起作用,所以我修改了一下:

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=`echo $buildNumber +1|bc`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
Run Code Online (Sandbox Code Playgroud)


Bin*_*ian 21

营销版本号是针对客户的,称为版本号.它从1.0和上升的主要更新到2.0,3.0,轻微的更新到1.1,1.2和bug修复1.0.1,1.0.2.此编号面向版本和新功能.

构建号主要是在此之前构建内部构建数.但有些人使用其他数字,如存储库的分支编号.这个数字应该是唯一的,以区分不同的几乎相同的构建.

如您所见,构建号不是必需的,由您决定使用哪个构建号.因此,如果您更新Xcode到主要版本,则构建字段为空.该版本字段不能为空!


要将构建号作为NSString变量:

NSString * appBuildString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
Run Code Online (Sandbox Code Playgroud)

要将版本号作为NSString变量:

NSString * appVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
Run Code Online (Sandbox Code Playgroud)

如果你想在一个NSString:

NSString * versionBuildString = [NSString stringWithFormat:@"Version: %@ (%@)", appVersionString, appBuildString];
Run Code Online (Sandbox Code Playgroud)

这是使用Xcode版本4.6.3(4H1503)测试的.内部版本号通常用括号/括号括起来.内部版本号为十六进制或十进制.

buildandversion


Xcode中,您可以通过在项目设置的构建阶段中放置以下内容,将构建号自动递增为十进制数Run script

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
Run Code Online (Sandbox Code Playgroud)

对于十六进制内部版本号,请使用此脚本

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$((0x$buildNumber)) 
buildNumber=$(($buildNumber + 1)) 
buildNumber=$(printf "%X" $buildNumber)
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
Run Code Online (Sandbox Code Playgroud)

project_settings


iHS*_*iHS 6

感谢@nekno和@ ale84获得了很好的答案.

但是,我修改了@ ale84的脚本,以增加浮点数的构建数量.

incl的值可以根据您的浮动格式要求进行更改.例如:如果incl = .01,输出格式为...... 1.19,1.20,1.21 ......

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
incl=.01
buildNumber=`echo $buildNumber + $incl|bc`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
Run Code Online (Sandbox Code Playgroud)