Everyone who has already built and shipped an iOS app to the AppStore knows the pain. That awful feeling when dealing with provisioning profiles, development and distribution certificates.
Published on Fri, November 27, 2015
I can't free you from that kind of experience, but here's a way that allows you to only go through it once.
Shipping a Xamarin iOS app to Apple follows usually those manual steps:
I think it's fair to say that those steps are hard to remember if you're not doing it every week, and it evidentially is error-prone. So setting up a new development machine once in a while can drive you crazy, and so can taking over the distribution task from a colleague who's normally doing this job but is not available at your important deadline.
That cries for automation.
Obviously everything has to be executed on a Mac, so it won't work on your average Windows box or on a Linux server. I highly recommend you to use a dedicated machine.
You need to install Xcode and its Command Line Tools, as well as Xamarin. The latter needs to run with an account that runs on the business plan, as you you need the "business feature" of headless builds to run all the stuff from the command line.
Everything described below can easily be run via simple shell scripts, but if you're running a fully featured build server like TeamCity or Jenkins anyway, go for it. I prefer it that way, but I won't go into any product specific details here because that would go beyond the scope of this post.
Yes, you need to do that – but hopefully the last time for a long, long time. If you've everything prepared, install the certificate (by double-clicking the *.p12) and the provisioning profile (likewise by double-clicking).
Protip:
When you've created a new certificate by the guidance of the Apple Website, don't only download it to your machine, but directly export the private key as a *.p12 file afterwards from the Keychain Access tool. Remember the password of that file, so you can import the certificate on any machine you need in the future. Otherwise you would always have to create a new certificat when setting up a new computer.
Make sure you're working on a clean and fresh working directory with the latest sources of your project (and maybe a specific branch). See this thread for an example for Git.
You will need to change some things in your Info.plist file that differ from your development configuration. Those things usually are CFBundleIdentifier, CFBundleVersion, and CFBundleShortVersionString. There's a nice tool around to help you with those changes, it's called PlistBuddy.
It's also the right point in the process for setting up a custom Root.plist, for example for hiding some development options from the iOS Settings app. Simply replace the one in your Settings.bundle directory within your app's root directory with another one used only for distribution.
Sample:
# Replacing the Root.plist
rm src/MyAppRoot/Settings.bundle/Root.plist
cp deployment/Root.Distribution.plist src/MyAppRoot/Settings.bundle/Root.plist
# Setting up the Info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.mydomain.myapp" src/MyAppRoot/Info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion 2.5.0" src/MyAppRoot/Info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString 2.5.0" src/MyAppRoot/Info.plist
You may restore your Nuget packages, if you're using Nuget [sic] and you may run Nunit and execute other steps necessary to correctly build your project as well.
Building your Xamarin app via the command line is easy:
/Applications/Xamarin Studio.app/Contents/MacOS/mdtool
-v build '--configuration:AppStore|iPhone' src/MyApp.sln
This will result in a bunch of files in src/MyAppRoot/bin/iPhone/AppStore.
None of the built files will be sufficient for distribution, so you need to create and sign an *.ipa file:
xcrun -sdk iphoneos PackageApplication
-v src/MyAppRoot/bin/iPhone/AppStore/MyApp.app
-o src/MyAppRoot/bin/iPhone/AppStore/MyApp.ipa
If you want to check everything went right, which means all your _.plist adjustments were applied correctly and the _.ipa is signed with your distribution certificate, you can make use of nomad:
ipa info MyApp.ipa
Last but not least you have to deploy your *.ipa to Apple, so you can publish it to your TestFlight users or submit it to the review process.
This can be done by the command line as well, all you need is this script and an user account with a Admin or Technical role, so it is allowed to upload builds.
Dealing with all the Apple stuff sometimes is hard, doing it again and again is a waste of lifetime. Automating this process is definitely worth the time, so you can do something more joyful with the time you gain.