Wireless Distribution of Enterprise iOS Apps

One of the tasks we are beginning to explore at AIS is developing and distributing mobile applications for our corporate clients. One common scenario will be for these apps to be available only for their employees, or a select group of their clients. So distribution through Apple’s App Store, for example, may not be an acceptable solution.

There are several options for distributing enterprise iOS applications, if we can’t (or don’t want to) go through the App Store:

1. Ad Hoc distribution. This involves building the distribution files, distributing them to the clients (via email or posting them to a server), and having them drag the files to iTunes and then synchronizing their devices. That’s a little messy. And it requires repeating the process every time there is an update to the app.

Again, this is a messy process, and will have to be repeated for each update and new app.

2. iPhone Configuration Utility. Apple’s iPhone Configuration Utility (Mac version; Windows version; documentation) is another option. This leaves the task to the system administrator, and is labor intensive. The SysAdmin will either need to attach to each device, and install the provisioning profiles and the apps, or email the configuration profile to each user. A generic profile can be used across the organization, but if username and password management are a part of the profiles, then it gets very complicated, very quickly. Again, this is a messy process, and will have to be repeated for each update and new app.

3. Mobile Device Management. The SysAdmin can install apps through MDM (Mobile Device Management, requires sign-in). Again, device management is required, but MDM allows for remote management once the device has been initially configured. When a new or updated app is available, the administrator creates a new payload, sends a push notification (through Apple’s Push Notification Service) to the appropriate client devices, and the devices execute the command (in this case pulling down and installing the app in the payload). If MDM is already a feature in the organization’s administration processes, this is a viable option.

4. Distribute apps wirelessly, using the Over the Air (OTA) process. This is the route I’ll discuss in detail, as it seems to be the most straightforward and easiest to implement of the available options, especially if MDM is not applicable. There are some wrinkles, too, which can automate the process of updating/upgrading the apps transparent to the users.

App Development and OTA Distribution Process Overview

There are several steps involved in app development and the OTA distribution process. From a high level, they include:

1. Develop the iOS app. Obviously, the app needs to be developed! The standard process is using Xcode, Apple’s IDE. You can also use MonoTouch, a cross-platform IDE and SDK that allows you to use C# and .Net to create natively compiled iOS apps.

2. In order to be able to distribute the app, you need to purchase an Enterprise Development License through Apple.

3. Once the license has been approved, and the app has been developed, a provisioning profile needs to be created through the iOS Provisioning Portal (you can only see this if you are logged in as a developer).

4. Once the provisioning profile is installed, build and archive the app.

5. Before you create the distribution objects, make sure you have the web server set up and properly configured.

6. Create the Distribution and save.

7. Push the IPA and Manifest files to the web server.

8. Create a link on a web page that will be available to the appropriate users.

9. Send the link out to users.

10. When a user clicks on link, a dialog will come up asking if they want to install the app.

11. When installed and tapped, another link will appear, confirming startup. Upon acceptance, the app will run.

We’ll now discuss #4 – 11 in detail.

Build and Archive the App

Assuming your app compiles and runs according to specifications, you should “Build and Archive” the application for distribution (Product -> Archive).

Upon successful completion of the archive process, Xcode’s Organizer will come up, listing all of the archives created for your apps. This is where you will actually create the distribution objects. But before you take that step…

Set Up and Configure the Web Server

Make sure you have a web server online and configured properly. The most important aspect of this is to make sure that the proper mime types have been added to the Mime Type Settings:

For Mac OS X Server:
application/octet-stream ipa
text/xml plist

For IIS:
.ipa application/octet-stream
.plist text/xml

You will also need to determine exactly where on the server the ipa and manifest files will be stored. For this example, we put MobileCaseWorker.ipa and MobileCaseWorker.plist in /apps/MCW/1.0/ (making the fully qualified path for our test app distribution server Knowing this path is important for the next step.

Create the Distribution Files

Now that you have the web server set up and the path established, go back to Organizer:

Click on the “Distribute…” button.

Select the appropriate archive, then click “Distribute…”

Select “Save for Enterprise or Ad-Hoc Deployment” and click “Next”.

Choose an identity, and click “Next”.

Give your distribution package a name, and make sure you select “Save for Enterprise Distribution”. The fields for Enterprise Distribution will appear. Fill out Application URL with the exact path (including the domain name and the ipa file name, including extension), as determined in the previous step. Thus, for this example, the path would be

Select where you want to save the distribution files and click “Save”.

Push Files to Web Server & Create Link on Page

Two files have now been created:

Both of these files need to be placed in the appropriate directory on your web server. Once that is done, create or modify, a web page to which the users will go to download the app. The page will have a link to the manifest file, but the structure is specific:

<a href="itms-services://?action=download-manifest&url=http://example.com/
manifest.plist">Install App</a>

So, for our example, it looks like this:

<a href="itms-services://?action=download-manifest&url=">Mobile Case Worker 1.0</a>


Once you have everything in place, you can send a link to this page to your users. They can then load the page into mobile Safari and tap the link:

When they tap the link and select Install, the download and installation process starts:

Once the app is installed, the user will be prompted one more time to allow the app to run on their device.  Once they accept, they’re good to go!

Additional Thoughts

There are some nuances and potential gotchas involved in this process:

1) The web server should be secure, especially if the applications being made available are sensitive.

2) With that in mind, you can embed a direct link in an email to the users.

3) If you want to get fancy, you an set up a version management system on the back-end, with appropriate code in the app itself. Every time you push up a new version of an app, the user will be restricted from using the app until the new version is installed. One way of doing this is to have the app poll the server every time the app starts up or is awakened. It can get the latest version number from the server and compare it to the currently running version. If a newer version is available, it will then post a modal dialog, with a link to the latest download. Once the app is updated, all should proceed normally.

4) The name you give the app in Xcode (Target Name), and the App ID you give it in the Provisioning Portal have to match exactly. Usually, the App ID will follow this format:

com.appliedis.Mobile-Case-Worker (companyurl.targetname)

In Xcode, select the Target, click on the Summary tab, and fill out the Bundle Identifier appropriately:

If there is a name mismatch, build errors will occur until this is corrected.

5) There is apparently a bug in Apple’s implementation of the “itms-services” protocol. No spaces, even if they are escaped or URL Encoded, are allowed in the file name or web folder structure.

6) If you forget to add the mime types identified above, a rather generic “Cannot connect to” message. We figured this one out the hard way….


In addition to the links provided throughout, we also got a big helping hand from this blog post at Syndicated Methods. That kept us from turning issue #6 into a half-day marathon of troubleshooting.

There are no “ideal” solutions to Enterprise iOS Application deployment. But with a little work, and enough foresight, the pain can be minimized and the process can be relatively transparent to your (or your clients’) users.

About Gregory Hill

Greg is a Senior Software Engineer with AIS. He is the new iOS development "subject matter expert". Prior to coming to AIS, he spent two-and-a-half years working independently, developing his own iOS apps and pitching product ideas to businesses in the Mid-Atlantic region. He has been involved in the software industry since the mid-80s, developing and supporting applications for such companies and institutions as Sony, Wadsworth Publishing and Johns Hopkins Hospital.

  • I just ran in to the bug you commented about where no space characters – escaped or not – can be in the url to an app manifest pList.

    What is pretty terrible is that it would be really nice if we could just create folders with the app’s name that we wish to deploy but Apple is making things more difficult than usual – again.

    I was hoping to simply perform a “urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]” on the URL and open it, but itms-services simply refuses to handle a properly formatted URL – and without any error reporting.

    You might like to know that the url parameter within the manifest .plist CAN have spaces in it – and they don’t even need to be escaped out.  It’s really strange.

    As if this process was not enough of a pain already.

  • Brandon Lehner

    Note: The method you describe above is the same for Ad-Hoc distribution. You do not need an Enterprise developer license to do this – any paid developer license will do.

  • Richard F

    The subtle difference here is by using an Enterprise distribution certificate, there are no restrictions on the number of devices and no need to collect and register any UDIDs. The mobile provisioning profile is bundled in the .ipa allowing any user within the enterprise to install apps OTA with no prior configuration.