Xcode中的版本与构建

时间:2011-07-27 21:48:16

标签: ios xcode

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

我的问题是:

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

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

7 个答案:

答案 0 :(得分:1182)

答案 1 :(得分:71)

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

- (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)"
}

答案 2 :(得分:51)

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

这样想:

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

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

使用它:

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

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

答案 3 :(得分: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"

答案 4 :(得分:21)

营销版本号适用于客户,称为版本号。它从 1.0 开始,然后进行 2.0 3.0 的主要更新,以便对 1.1 进行微小更新,< em> 1.2 以及 1.0.1 1.0.2 的错误修复。这个数字是关于版本和新功能的。

内部版本号主要是内部版本号,直到那时为止。但有些人使用其他数字,例如存储库的分支编号。这个数字应该是 unique ,以区分不同的几乎相同的构建。

如您所见,内部版本号不是必需的,您可以使用哪个内部版本号。因此,如果您将Xcode更新为主要版本,则 build 字段为空。 版本字段可能不为空!。


要将构建号码作为NSString变量:

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

要将版本号码作为NSString变量:

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

如果您想在一个NSString

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

使用 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"

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

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

答案 5 :(得分:6)

感谢@nekno和@ ale84提供了很好的答案。

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

可以根据浮动格式要求更改incl的值。 例如:if 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"

答案 6 :(得分:1)

另一种方法是在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];
}