我有一个用Xcode 3开发的应用程序,最近开始用Xcode 4编辑。在目标摘要中,我有带有字段的iOS应用程序目标表单:标识符、版本、构建、设备和部署目标。版本字段是空白的,构建字段是3.4.0(这与我仍然使用Xcode 3编辑应用程序时的版本相匹配)。
我的问题是:
版本和构建字段之间的区别是什么? 为什么我升级到Xcode 4后版本字段是空的?
我有一个用Xcode 3开发的应用程序,最近开始用Xcode 4编辑。在目标摘要中,我有带有字段的iOS应用程序目标表单:标识符、版本、构建、设备和部署目标。版本字段是空白的,构建字段是3.4.0(这与我仍然使用Xcode 3编辑应用程序时的版本相匹配)。
我的问题是:
版本和构建字段之间的区别是什么? 为什么我升级到Xcode 4后版本字段是空的?
当前回答
感谢@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"
其他回答
(只是把这个留在这里供我自己参考。)这将显示你在Xcode目标中看到的"version"和"build"字段的version和build:
- (NSString*) version {
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
return [NSString stringWithFormat:@"%@ build %@", version, build];
}
在斯威夫特
func version() -> String {
let dictionary = NSBundle.mainBundle().infoDictionary!
let version = dictionary["CFBundleShortVersionString"] as? String
let build = dictionary["CFBundleVersion"] as? String
return "\(version) build \(build)"
}
营销发布号是针对客户的,称为版本号。它从1.0开始,主要更新到2.0、3.0,次要更新到1.1、1.2,错误修复到1.0.1、1.0.2。这个数字是面向发布和新功能。
构建号主要是在此之前构建的内部编号。但有些使用其他数字,如存储库的分支编号。这个编号应该是唯一的,以区分几乎相同的不同构建。
如您所见,版本号不是必需的,由您决定要使用哪个版本号。所以如果你把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)测试的。版本号通常用括号/大括号表示。构建号为十六进制或十进制。
在Xcode中,你可以通过在项目设置的Run脚本构建阶段中放置以下内容,将构建号自动增加为十进制数
#!/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"
我在Xcode 14.2上,并将以下bash脚本添加到项目包中的.sh文件中。然后我使用一个运行脚本构建阶段来调用这个脚本。当我存档项目时,版本和包更新了几次,但随后停止了增量。关于为什么脚本不会继续增加有任何反馈吗?感谢反馈。
currentVersionString=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$PROJECT_DIR/SupportingFiles/$INFOPLIST_FILE")
currentBuildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$PROJECT_DIR/SupportingFiles/$INFOPLIST_FILE")
newBuildNumber=$((currentBuildNumber + 1))
IFS='.' read -ra version <<< "$currentVersionString"
version[2]=$((version[2] + 1))
newVersionString="${version[0]}.${version[1]}.${version[2]}"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $newVersionString" "$PROJECT_DIR/SupportingFiles/$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $newBuildNumber" "$PROJECT_DIR/SupportingFiles/$INFOPLIST_FILE"
苹果在某种程度上重新安排了这些领域。
接下来,如果你查看你的应用目标的信息选项卡,你应该使用“Bundle versions string, short”作为你的版本(例如,3.4.0)和“Bundle Version”作为你的构建(例如,500或1A500)。如果你不能同时看到它们,你可以添加它们。这些将映射到Summary选项卡上适当的Version和Build文本框;它们是相同的值。
当查看信息选项卡,如果你右键单击并选择显示原始键/值,你会看到实际的名称是CFBundleShortVersionString(版本)和CFBundleVersion(构建)。
版本通常是你在Xcode 3中使用它的样子。我不确定你问的版本/构建的差异在什么层面上,所以我将哲学地回答这个问题。
有各种各样的方案,但最受欢迎的是:
(MajorVersion} (MinorVersion)。(该国的)
主要版本-主要的更改、重新设计和功能 变化 小版本-小的改进,增加功能 Revision——修复bug的补丁号
然后,Build被单独用于指示一个版本或整个产品生命周期的构建总数。
许多开发人员从0开始构建编号,并且每次构建他们都会将该数字增加1,一直增加下去。在我的项目中,我有一个脚本,每次构建时自动增加构建数。参见下面的说明。
Release 1.0.0可能是build 542。它花了542个构建才达到 1.0.0版本。 1.0.1版可能是578版。 1.1.0版可能是build 694。 2.0.0版可能是949版。
其他开发者,包括苹果,都有一个由主版本+次版本+版本号组成的版本号。这些是实际的软件版本号,而不是用于营销的值。
如果你进入Xcode菜单> About Xcode,你会看到版本号和版本号。如果你点击更多信息…按钮,你会看到一堆不同的版本。由于更多信息…按钮在Xcode 5中被移除,此信息也可以从系统信息应用程序的软件>开发人员部分获得,通过打开苹果菜单> About this Mac > System Report....获得
例如,Xcode 4.2 (4C139)。营销版4.2是构建主版本4、构建小版本C和构建139。下一个版本(大概是4.3)可能是Build release 4D, Build编号将从0开始并从那里增加。
iPhone模拟器版本/构建号也是如此,iPhone、mac等也是如此。
3.2: (7 w367a) 4.0: (8 a400) 4.1: (8 b117) 4.2: (8 c134) 4.3: 8 (h7)
更新:根据请求,下面是创建一个脚本的步骤,每次在Xcode中构建应用程序时运行该脚本,读取构建号,增加它,并将其写回应用程序的{app}-Info。plist文件。如果你想把你的版本号/版本号写入Settings.bundle/Root*,还有一些可选的附加步骤。plist文件(s)。
这是从这里的入门文章扩展而来的。
在Xcode 4.2 - 5.0:
Load your Xcode project. In the left hand pane, click on your project at the very top of the hierarchy. This will load the project settings editor. On the left-hand side of the center window pane, click on your app under the TARGETS heading. You will need to configure this setup for each project target. Select the Build Phases tab. In Xcode 4, at the bottom right, click the Add Build Phase button and select Add Run Script. In Xcode 5, select Editor menu > Add Build Phase > Add Run Script Build Phase. Drag-and-drop the new Run Script phase to move it to just before the Copy Bundle Resources phase (when the app-info.plist file will be bundled with your app). In the new Run Script phase, set Shell: /bin/bash. Copy and paste the following into the script area for integer build numbers: buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE") buildNumber=$(($buildNumber + 1)) /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE" As @Bdebeez pointed out, the Apple Generic Versioning Tool (agvtool) is also available. If you prefer to use it instead, then there are a couple things to change first: Select the Build Settings tab. Under the Versioning section, set the Current Project Version to the initial build number you want to use, e.g., 1. Back on the Build Phases tab, drag-and-drop your Run Script phase after the Copy Bundle Resources phase to avoid a race condition when trying to both build and update the source file that includes your build number. Note that with the agvtool method you may still periodically get failed/canceled builds with no errors. For this reason, I don't recommend using agvtool with this script. Nevertheless, in your Run Script phase, you can use the following script: "${DEVELOPER_BIN_DIR}/agvtool" next-version -all The next-version argument increments the build number (bump is also an alias for the same thing), and -all updates Info.plist with the new build number. And if you have a Settings bundle where you show the Version and Build, you can add the following to the end of the script to update the version and build. Note: Change the PreferenceSpecifiers values to match your settings. PreferenceSpecifiers:2 means look at the item at index 2 under the PreferenceSpecifiers array in your plist file, so for a 0-based index, that's the 3rd preference setting in the array. 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 If you're using agvtool instead of reading the Info.plist directly, you can add the following to your script instead: 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 And if you have a universal app for iPad & iPhone, then you can also set the settings for the iPhone file: /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
另一种方法是在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];
}