Engineering blog from Studio Drydock.

Deploying iOS Builds Locally

First published 26 January 2019

If you’re building iPhone and iPad apps, you’ll want a convenient way to deploy builds to your own devices for testing and quick feedback. There are quite a few ways of going about this:

With OTA distribution, you can download a recent build of your app from any device over WiFi, by tapping a link on a web page from that device.

The whole pipeline

Before getting into the details, let’s go over the goal and all the different pieces that are needed.

The end goal is to install the Application (a .ipa file built from Xcode) onto the device. This will be served by the Web Server, but iOS can’t install it directly from the browser.

Instead, the device reads an OTA Manifest file (in .plist format) which provides some simple metadata about the app, including the URL of the application itself.

iOS will not install apps over an insecure connection; the manifest must be served over HTTPS. Furthermore, this must be a connection with a trusted certificate. One way to do this is to host a public web server and use a service like Let’s Encrypt to obtain a trusted certificate, but this is not always appropriate for internal developer builds.

Instead, we will sign our own certificate for the web server. As of iOS 12, a self-signed certificate is not sufficient for it to be trusted, even if the certificate is installed on the device. Instead, we must create a Certificate Authority (CA) and have that sign the certificate.

In order to have the iOS device trust our Certificate Authority, we need to install the authority’s Root Certificate on the device. Since iOS 12, this must be done via a Configuration Profile (.mobileprofile), which is a simple file that encapsulates the root certificate.

Once all of this is set up, the user can:

  1. Download, install and trust the Configuration Profile, which causes the device to accept our Certificate Authority. This only needs to be done once per device.
  2. Install or update the app by clicking on a link to the OTA Manifest.

Create Certificates

The goal here is to obtain:

I followed the instructions at How to Create Your Own SSL Certificate Authority for Local HTTPS Development to create the CA and both of these certificates (there’s no need to install the certificate on your computer though).

Set up Web Server

Your web server must be configured to serve HTTPS using the web certificate generated above. For this step, I followed the instructions at Set up a Self Signed Certificate on macOS’s Built in Apache (although we are using a CA-signed certificate, not self-signed).

At this point you should be able to browse your web site over HTTPS, albeit with security warnings indicating that the site is not secure (because your CA is not trusted yet).

The web server must also serve the following MIME types for the manifest and application files:

For Apache, these are set up in /etc/apache/mime.types; add the plist and ipa extensions to the existing application/xml and application/octet-stream entries, respectively.

Configuration Profile

In order to install the Root Certificate on an iOS device, it must be packaged in a Configuration Profile (.mobileprofile).

This is easy to create using Apple Configurator 2 from the MacOS App Store — just create a new profile and add the root certificate. There are some more detailed instructions at iPhone Mobile Profile for a new CA root certificate.

This profile should be made available from your web server over HTTP. Users will be prompted to install the profile (with many warnings about its dubious source!). After the profile is installed, it still needs to be added to the trusted root store manually, by opening the Settings / General / About / Trust Certificate Settings and toggling the option for your profile.

At this point you should be able to browse your web server over HTTPS without seeing any security warnings. (Note that this is not just a convenience, it is required for apps to install).

OTA Manifest

The OTA Manifest is a simple Property List (.plist) file in XML format which describes basic metadata about the app and its download location.

See this Sample Manifest File.

Upload the manifest and app (.ipa) to your website, ensuring they have read permissions available.

Linking to the Manifest

The final step is to create an HTML page with links to each build. The link must be of the form:

<a href="itms-services://?action=download-manifest&url=">Awesome App</a>

That’s it! Click the link and return to the home screen to see the app install.

In the future I should write about how to automate build delivery to the web server, and how to generate the manifest files and links automatically.


If instead of great success you see an error message on device, check the device console log for a more detailed error message.

A checklist of requirements:

Thanks to for the stock icons in the pipeline diagram.