Jon Simpson
Versioning & Xcode 4 Info.plist Processing
On upgrading to Xcode 4.3 (now as a normal app bundle from the Mac App Store, rather than an installer), I found that the usual git describe output we use to generate long versioning information for our apps has gained white space between the dashes (e.g. 1.0rc14-12-g45b2748
becomes 1.0rc14 - 12 - g45b2748
in the app).
We’ve been using Fraser Hess’ Git build tagging technique since the outset of the project and it’s been extremely useful to see at a glance whether builds contains major changes off the latest tag, and which git revision they represent at a glance.
After doing some initial investigation, the output of git describe is still being captured without the spaces into Xcode and placed into the intermediary #define
.
Conventional wisdom before Xcode 4 determined that the CFBundleShortVersionString
field in an App’s Info.plist
could take any value, and the CFBundleVersion
should be a monotonically increased integer, which was used by the system for programmatic use (determining latest versions etc.)
However, it appears that Apple have changed the definitions of these fields, and now CFBundleShortVersionString
is strictly defined as expecting a typically formatted marketing version number.
CFBundleShortVersionString
(String
- iOS, Mac OS X) specifies the release version number of the bundle, which identifies a released iteration of the application. The release version number is a string comprised of three period-separated integers.Apple Developer - Information Property List Key Reference: Core Foundation Keys
(As an aside, it would be helpful if Apple would expose the revision information for their Developer Documentation, so it’d be possible to track down when exactly this definition changed.)
Given this information, it would appear Xcode 4.3 is now parsing the CFBundleShortVersionString
field with the preprocessor where previous versions have left it verbatim.
Our app makes use of the version string for client version checking against a remote API, so keeping the additional padding is not ideal.
A quick look at Apple’s notes on Info.plist pre-processing reveals that tokens will have whitespace appended to them unless the -traditional
flag is set on the Info.plist
preprocessor flags of the project, in testing though the -traditional
flag has no effect on this space padding around hyphens.
To avoid the pre-processor entirely (and avoid the need for a separate Version target), the same result can be achieved by directly writing the output of git describe
into the plist file using plistbuddy
.
For now we’re using a build phase which runs the following script.
GIT=`which git`
GIT_DESCRIBE=`$GIT describe`
echo "Git describe output: $GIT_DESCRIBE"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $GIT_DESCRIBE" "Info.plist"
This is definitely a hack but less invasive (no extra target, magic values set in the Info.plist) than the original solution and means that Xcode can see the values in the plist from the last build (the UI can show the ShortVersionString from last build)- the downside with this is that we’re blindly ignoring any constraints that the toolchain want to place on the key, as it’s written in without their involvement.