ASP.Net ipa Installer

This little project cdm about because of a need to install an ipa from our TeamCity (our CI server). I’ve heard people fawning all over Jenkins, but I have very mixed feelings on open source. Sometimes it’s great, and sometimes you start contributing to an open source project and find yourself wondering how the thing ever managed to work in the first place. Which is not to say that paid software doesn’t have that problem,  but in my experience it involves more people with degrees… usually.

Ranting aside, the basic idea of this project is to have a web page that you can go to, type in some information about a build artifact and then install straight from the web page.

In order to accomplish this, we will be making something like this


This is easily extendable, but I don’t need things to be complicated. The way it works is someone will go to this page, enter in the artifact’s build number and hit install application, then the ipa will be downloaded and installed from our CI server. This keeps our QA from having to know anything other than the build number (which they know from our issue tracking software)

The page uses ASP.Net MVC’s default bootstrap theme, and we’ll use Angular.js to formulate the url for the install application button.

Installing and ipa

Unfortunately, things are not as simple as just downloading the ipa and saying install. In fact, the ability to get to the ipa doesn’t really do much for you. You could download the ipa and then use iTunes to install it, but where’s the fun in that?

Here’s how things work:  itms-services:// is a url schema that iOS handles. what you need to do is formulate a url like this

and the url needs to be referencing a plist that looks something like this

Once you have the plist somewhere and the ipa somewhere, you just need to open the link in safari.

NOTE: as of iOS 7.1, your url to the plist (in the itms-source url) MUST USE HTTPS. It will not work with http, though it seems to work just fine with self signed certificates. Prior to iOS 7.1, you could use http.

Serving up the Plist from ASP.Net

Here’s  a neat little trick I learned while doing this. You can just create a cshtml file, and put the xml inside it. That way you get all the benefits of the Razor stuff, and you don’t have to parse xml manually. It’s really neat.

We’ll create a cshtml template for the plist we want to generate, then we’ll have the controller accept some parameters to dynamically generate the plist we need.

Inside of the cshtml, we manually set the content type to “application/xml” you could also use “text/xml”. And we manually reset the Layout. If you don’t do this, you may end up accidentally rendering your xml inside of your html layout document.

We’ll just pass the URL to download the ipa in to the cshtml with the ViewBag. you could totally create a model, but I didn’t bother because this was rapid prototyping when I implemented it.

Then on your controller, you just need something like this to serve up the dynamically generated plist


Making the Page Work

Now that we have dynamically generated plists for installation, we need to make the Install Application button have something similar to this for the href

To the _Layout I added
and the script tag to pull the mi Angular.js 1.2.2 then index.cshtml looks like this

And the InstallerController looks like this

I didn’t feel like declaring my module in a separate file for such a small project, so I just did it at the top of my controller. Also notice that you have to do

otherwise angular.js will turn the ng-href into a
url, and that breaks things.

You also have to make sure that if you have url encoded parameters in your url to the ipa, you must encode them to prevent the items services from mis-parsing the url

Leave a Comment

Your email address will not be published. Required fields are marked *