For awhile, I had wanted to include the svn revision number in my iOS app, and when I came across a blog post by Daniel Jalkut from a few years ago, I thought I had found an answer. No sooner than I implemented his script, though, did I discover that Apple doesn’t allow build numbers in iOS app packages.
I still really wanted this information in my dev builds so it would be easier to keep track of what version I was working with, so wound up I made a number of modifications to the script to make it suit my needs:
* When building, if the current build style is Debug, do nothing.
* Use the INFOPLIST_PATH environment variable to dynamically generate the path to the Info.plist (so it works on iOS as well as Mac OS apps).
* Dynamically insert the revision information into the plist, rather than requiring a marker.
* Read and write out the plist to the binary format iOS apps want.
This code is free to use. Enjoy!
Installation Instructions
You’ll need to add this as a new build phase in Xcode. For your target, you’ll want to create a new “Run Script” build phase, and copy and paste the code in. You’ll want to set the shell to your perl interpreter; I use /usr/bin/perl -w.
The Code
# Xcode auto-versioning script for Subversion
# Original version by Axel Andersson
# Modifications by Daniel Jalkut <http://www.red-sweater.com/blog/23/automatic-build-sub-versioning-in-xcode>
# Further improvements by John Bafford <http://bafford.com>
use strict;
die "$0: Must be run from Xcode" unless $ENV{"BUILT_PRODUCTS_DIR"};
# Do nothing in a Debug build.
exit(0) if($ENV{'BUILD_STYLE'} ne 'Debug');
# Get the current subversion revision number and use it to set the CFBundleVersion value
my $version;
my $REV = `/usr/bin/svnversion -n ./`;
my $INFO = "$ENV{BUILT_PRODUCTS_DIR}/$ENV{INFOPLIST_PATH}";
# (Match the last group of digits and optional letter M/S); regex via Kevin "Regex Nerd" Ballard
($REV =~ m/\d+[MS]*$/) && ($version = $&);
die "$0: No Subversion revision found" unless $version;
my $match = "(<key>CFBundleVersion</key>\n\t<string>)((.*?)( \(.*\))?)(</string>)";
my $info = `plutil -convert xml1 $INFO -o -`;
$info =~ s/$match/$1$3 ($version)$6/;
open(FH, "|plutil -convert binary1 -o $INFO -") or die "$0: $INFO: $!";
print FH $info;
close(FH);
