版本与构build在XCode

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

我的问题是:

  1. 版本和生成字段有什么区别?

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

谢谢。

苹果公司重新排列/重新安置了田地。

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

查看“信息”选项卡时,如果右键单击并select“ 显示原始键/值” ,则会看到实际名称为CFBundleShortVersionString (Version)和CFBundleVersion (Build)。

这个版本通常是用来表示你已经在Xcode 3中使用它了。我不确定你在问什么级别的版本/构build差异,所以我会回答它的哲学。

有各种各样的计划,但受欢迎的是:

{MajorVersion}。{MinorVersion}。{}修订

  • 主要版本 – 主要更改,重新devise和function更改
  • 次要版本 – 小的改进,function的增加
  • 修订版 – 修补程序的修补程序号

然后,构build单独使用,以指示版本或整个产品生命周期的构build总数。

许多开发人员在0处启动Build编号,每次构build时都会将编号增加1,永远增加。 在我的项目中,我有一个脚本,每次构build时都会自动增加构build编号。 请参阅下面的说明。

  • 版本1.0.0可能构build542.它需要542个版本才能达到1.0.0版本。
  • 版本1.0.1可能会build立578。
  • 版本1.1.0可能会build立694。
  • 版本2.0.0可能会build立949。

包括苹果在内的其他开发人员的内部版本号包含主版本+次版本+版本号。 这些是实际的软件版本号,而不是用于市场营销的值。

如果你去Xcode菜单> 关于Xcode ,你会看到版本号和内部版本号。 如果你点击更多信息…button,你会看到一堆不同的版本。 由于Xcode 5中的“ 更多信息…”button已被删除,因此通过打开Apple菜单>“ 关于本机” >“ 系统报告…” ,也可从系统信息应用程序的软件>开发人员部分获取此信息。

例如,Xcode 4.2(4C139)。 市场版本4.2是build立主要版本4,build立次要版本C和build立编号139.下一个版本(推测4.3)可能是生成版本4D,并且build立编号将从0开始并且从那里增量。

iPhone模拟器版本/内部版本号与iPhone,Mac等一样。

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

更新 :通过请求,下面是创build一个脚本的步骤,每次在Xcode中构build应用程序时都会运行脚本来读取Build号码,将其增加,然后将其写回到应用程序的{App}-Info.plist文件中。 如果要将版本/内部版本号写入Settings.bundle/Root*.plist文件,则还有可选的附加步骤。

这是从这篇how-to文章扩展而来的。

在Xcode 4.2 – 5.0中:

  1. 加载你的Xcode项目。
  2. 在左侧窗格中,单击层次结构顶部的项目。 这将加载项目设置编辑器。
  3. 在中心窗格的左侧,点击TARGETS标题下的应用程序。 您将需要为每个项目目标configuration此设置。
  4. select“ 构build阶段”选项卡。
    • 在Xcode 4的右下angular,点击Add Build Phasebutton并selectAdd Run Script
    • 在Xcode 5中,select编辑器菜单> 添加生成阶段 > 添加运行脚本生成阶段
  5. 拖放新的“运行脚本”阶段,将其移动到“ 复制包资源”阶段之前(app-info.plist文件将与您的应用程序捆绑在一起时)。
  6. 在新的运行脚本阶段,设置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" 

    正如@Bdebeez指出的那样, 苹果通用版本工具 ( agvtool )也是可用的。 如果你喜欢使用它,那么有几件事情需要改变:

    • select生成设置选项卡。
    • 在“ 版本控制”部分下,将“ 当前项目版本”设置为要使用的初始版本号,例如1
    • 返回到“ 构build阶段”选项卡上,在“ 复制包资源 阶段之后拖放“运行脚本”阶段,以避免在尝试构build和更新包含构build编号的源文件时出现争用情况。

    请注意,使用agvtool方法,您可能仍会定期获取失败/已取消的构build,而且没有任何错误。 出于这个原因,我不build议在这个脚本中使用agvtool

    不过,在“运行脚本”阶段,您可以使用以下脚本:

     "${DEVELOPER_BIN_DIR}/agvtool" next-version -all 

    next-version参数会增加next-version号( bump也是同一个事件的别名),并且会使用新的版本号更新Info.plist

  8. 如果您有显示版本和版本的设置包,则可以将以下内容添加到脚本末尾以更新版本和版本。 注意:更改PreferenceSpecifiers值以匹配您的设置。 PreferenceSpecifiers:2表示查看plist文件中PreferenceSpecifiers数组下的索引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 

    如果您正在使用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 
  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 

(只是把它留在这里供我自己参考。)这将显示在Xcode目标中看到的“version”和“build”字段的版本和构build:

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

在Swift中

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

内部编号是一个内部编号,表示应用程序的当前状态。 它不同于版本号,因为它通常不是面向用户的,并且不象版本号通常那样表示任何差异/特征/升级。

像这样想:

  • 构build( CFBundleVersion ):构build的数量。 通常你从1开始,每增加一个应用程序就增加1。 它可以快速地比较哪个版本更新,它代表了代码库的进度感。 在使用QA进行工作时,这些可能是非常有价值的,并且需要确保在正确的构build中logging错误。
  • 营销版本( CFBundleShortVersionString ):用于表示您的应用的此版本的用户正在使用的号码。 通常这遵循Major.minor版本计划(例如MyAwesomeApp 1.2),以便让用户知道哪些发行版是较小的维护更新,哪些是很大的新function。

为了在您的项目中有效地使用它,Apple提供了一个称为agvtool的强大工具。 我强烈build议使用这个,因为它比脚本更改更简单。 它使您可以轻松设置内部版本号和市场营销版本。 在编写脚本时(例如,轻松更新每个版本的内部版本号,甚至查询当前内部版本号是什么),该function特别有用。 它甚至可以做更多的奇特的事情,如更新内部版本号时为您添加SVN标签。

要使用它:

  • 在版本控制下的Xcode中将项目设置为使用“Apple Generic”。
  • 在terminal
    • agvtool new-version 1 (将agvtool new-version 1设置为1)
    • agvtool new-marketing-version 1.0 (设置营销版本为1.0)

查看agvtool的手册页获取大量信息

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

 #!/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" 

营销发布号码是针对客户的,称为版本号 。 它从1.0开始,主要更新到2.0,3.0 ,对1.1,1.2进行小的更新,并修复到1.0.1,1.0.2 。 这个数字是关于发布和新function的。

内部 版本号大部分是在此之前制作内部版本号 。 但有些使用其他数字,如存储库的分支号码。 这个数字应该是唯一的,以区分几乎相同的构build。

正如你所看到的,内部版本号是没有必要的,它取决于你想要使用的内部版本号 。 所以,如果你更新你的Xcode到一个主版本,生成字段是空的。 版本字段可能不是空的!


将内部版本号作为NSStringvariables获取:

 NSString * appBuildString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; 

要将版本号作为NSStringvariables:

 NSString * appVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 

如果你想同时在一个NSString

 NSString * versionBuildString = [NSString stringWithFormat:@"Version: %@ (%@)", appVersionString, appBuildString]; 

这是用Xcode版本4.6.3(4H1503)进行testing。 内部版本号通常写在括号/大括号中。 内部版本号是hex或十进制。

buildandversion


Xcode中,您可以通过在项目设置的Run script构build阶段中放置以下内容来自动递增内部版本号作为十进制数字

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

对于hex内部版本号使用这个脚本

 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" 

project_settings

感谢@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" 

另一种方法是在appDelegate didFinishLaunchingWithOptions中设置版本号:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSString * ver = [self myVersion]; NSLog(@"version: %@",ver); NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:ver forKey:@"version"]; return YES; } - (NSString *) myVersion { NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]; return [NSString stringWithFormat:@"%@ build %@", version, build]; }