A follow-up (sort of) to this question: in the Xcode build tab, I set my Base SDK to 3.1 but after uploading to the App Store, I see it being listed as requiring 2.2 or later. Why is that?
Both Base SDK and Deployment Target are set to 3.1.
iphonexcode
A follow-up (sort of) to this question: in the Xcode build tab, I set my Base SDK to 3.1 but after uploading to the App Store, I see it being listed as requiring 2.2 or later. Why is that?
Both Base SDK and Deployment Target are set to 3.1.
Okay I've managed to figure it out after much reading!
Basically, the Active SDK is just a build time override of the Base SDK. By default, when the Base SDK changes it automatically changes the Deployment Target to the same OS as the SDK. So when I wanted to build the app under the 3.1.2 SDK but have it run on 3.0 OS, I changed the Active SDK to 3.1.2, but that had automatically changed the minimum OS (deployment target). I saw this by looking at the Info.plist file in the package contents in my .app file.
So the best thing to do is to set the Base SDK to the latest SDK (currently 3.1.2) and then manually set the Deployment Target to 3.0 OS. Once the 2 are different then it will no longer automatically change.
However, this means that your app can install on a 3.0 device that may have 3.0, 3.1, or 3.1.2 SDKs. Therefore, any frameworks, methods or properties you use that are only available in SDKs greater than 3.0 you will have to use conditionally.
When you get around to building the app, ensure that that Active Target is set as the same as your Base SDK, e.g. Device 3.1.2. But remember to compile your app under Device 3.0, Device 3.1, and Device 3.1.2 just to check for compiler warnings. This will ensure that you don't have any code accessing methods/frameworks that don't exist in any SDKs down to your Deployment Target.
I hope this helps anyone who is in my position and couldn't find a simple explanation of how it all works.
The SDK Compatibility Guide was very useful and informative. However it took just a little extra figuring out for me to be comfortable with the concept and how everything works. This image from the guide is useful:
(source: apple.com)
Apple sort of rearranged/repurposed the fields.
Going forward, if you look on the Info tab for your Application Target, you should use the "Bundle versions string, short" as your Version (e.g., 3.4.0) and "Bundle version" as your Build (e.g., 500 or 1A500). If you don't see them both, you can add them. Those will map to the proper Version and Build textboxes on the Summary tab; they are the same values.
When viewing the Info tab, if you right-click and select Show Raw Keys/Values, you'll see the actual names are CFBundleShortVersionString
(Version) and CFBundleVersion
(Build).
The Version is usually used how you appear to have been using it with Xcode 3. I'm not sure on what level you're asking about the Version/Build difference, so I'll answer it philosophically.
There are all sorts of schemes, but a popular one is:
{MajorVersion}.{MinorVersion}.{Revision}
Then the Build is used separately to indicate the total number of builds for a release or for the entire product lifetime.
Many developers start the Build number at 0, and every time they build they increase the number by one, increasing forever. In my projects, I have a script that automatically increases the build number every time I build. See instructions for that below.
Other developers, including Apple, have a Build number comprised of a major version + minor version + number of builds for the release. These are the actual software version numbers, as opposed to the values used for marketing.
If you go to Xcode menu > About Xcode, you'll see the Version and Build numbers. If you hit the More Info... button you'll see a bunch of different versions. Since the More Info... button was removed in Xcode 5, this information is also available from the Software > Developer section of the System Information app, available by opening Apple menu > About This Mac > System Report....
For example, Xcode 4.2 (4C139). Marketing version 4.2 is Build major version 4, Build minor version C, and Build number 139. The next release (presumably 4.3) will likely be Build release 4D, and the Build number will start over at 0 and increment from there.
The iPhone Simulator Version/Build numbers are the same way, as are iPhones, Macs, etc.
Update: By request, here are the steps to create a script that runs each time you build your app in Xcode to read the Build number, increment it, and write it back to the app's {App}-Info.plist
file. There are optional, additional steps if you want to write your version/build numbers to your Settings.bundle/Root*.plist
file(s).
This is extended from the how-to article here.
In Xcode 4.2 - 5.0:
/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:
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
Best Answer
In Xcode, there is a different set of Base SDK and Deployment target values for the project, than for the Target. My project had the correct values set, but the Target had 2.2 set for Deployment Target.
I'm not sure yet what the Deployment Target in the Build settings for the Project is supposed to do, but the Deployment Target for the Target is what gets used by the iTunes App Store.