Automatic iOS Enterprise Distribution in Titanium
So let’s say you’ve got an Enterprise Distribution License with Apple, and
you’re writing an app with Appcelerator’s Titanium. You want to be able to
.ipa to your server with a single command. You’ll need to automate
a couple things:
- Building the project in Titanium
- Code signing to produce an
- Uploading to your server
- Updating your
.plistfile to point to the correct
.ipaor setting up a symbolic link so the
.plistwill point to the current
make in my project to handle the automation. Below are snippets of
some of my
Makefile rules which should help you automate your build process.
Automating the Titanium Build
This rule assumes that the current directory is a Titanium project (hence the
pwd). It requires a couple of make variables:
PYTHON: path of python executable, like /usr/local/bin
IOS_BUILDER: path of the Titanium iOS builder.py. This is probably something like
IOS_VER: The iOS sdk to build against. For example,
IOS_ID: The iOS App ID. For example,
com.myapp.example. This must match the ID associated with the Enterprise Distribution cert you will use.
APP_NAME: The name of the application.
MOBILEPROVISION: The ID of the mobile provisioning profile. You can find this in the Xcode organizer: hit devices on the top, then hit provisioning profiles on the side. The id will look something like
DEVIDENT: Developer identity. This is what appears after ‘iPhone Distribution:’ in your developer identity. So, if your developer identity is ‘iPhone Distribution: Example co.’, you would set this to ‘Example co.’.
I also pipe this through
egrep to get rid of all debug messages for cleaner
This will compile a
.app for you; now, we’ll need to sign it to create an
.ipa for distribution.
Automatic Code Signing
This rule will use
xcrun to perform the actual packaging of the app. Only
one additional variable is introduced:
DISTRIB_PROFILE: The developer identity used for distribution. This includes the ‘iPhone Distribution:’ part, so it should look something like ‘iPhone Distribution: Example co.’.
This will create an
.ipa file in your build folder. This will need to be
copied to the server which will be distributing your application.
These two lines simply scp the file over and then symlink your app name to the
latest version of your app.
$(GITDESCRIBE) could be any type of description
of the current version; in my case it’s
git describe --always. If you’re
using svn or mercurial or (gasp) cvs, set this variable to whatever identifies
the current checked out revision.
Putting it all together, we have the following rule:
and your latest version is on your server, waiting to be downloaded.
Automatic updating, too!
You’ll first have to find a way for the server to be able to report the current
version available. I do this by having a
motd.json file with a
field which indicates the current client
.ipa available on the server. When
I deploy, I have a rule which will shell into the deployment server and
that line in the
Every time the client is started, it pulls this
motd.json file and checks
its version against the server’s version. If they differ, it pulls a new
.ipa off the server.
Not the most elegant solution, I know; but, as I only write a single app at the moment, I haven’t yet invested the time into writing some kindof open source deployment architecture. It’s an idea, though.
motd.json may look something like:
So, we’ll write a simple rule to sed this to be the current
Your client app must also have knowledge of it’s current revision. You can
do this by creating a
revision.js file in your
This file can now be
require()d to obtain the current version. Now, your
distribute rule will look like this:
motd.json from the server, check the version, and
itms-services url in order to start the upgrade. The following example is
very bare; you most likely want to pop up a window informing the user that
an update is available:
To use this snippet, we’ll have to require it elsewhere and invoke the
When the above bit is run, a box will pop up saying ‘Developer would like to install Application’ when an update is available.
This is a great way to quickly deploy to enterprise customers. You may also be able to use a similar method to the above for deploying to beta testers, though I have not tested this.
Enjoy & good luck.
blog comments powered by Disqus