Enterprise app deployment doesn't work on iOS 7.1
We distribute apps via an Enterprise account, using an itms-services://
URL. This has always worked fine, but after installing the iOS 7.1 beta on our iPad it refuses to install. Instead we just get the generic Cannot connect to example.com
message that iOS unhelpfully displays when there is any sort of problem downloading the app.
I've been unable to find anything here on SO, on Google or in the 7.1 release notes to suggest what could be causing the problem.
I found the issue by connecting the iPad to the computer and viewing the console through the XCode Organizer while trying to install the app. The error turns out to be:
Could not load non-https manifest URL: http://example.com/manifest.plist
Turns out that in iOS 7.1, the URL for the manifest.plist
file has to be HTTPS, where we were using HTTP. Changing the URL to HTTPS resolved the problem.
I.e.
itms-services://?action=download-manifest&url=http://example.com/manifest.plist
becomes
itms-services://?action=download-manifest&url=https://example.com/manifest.plist
I would assume you have to have a valid SSL certificate for the domain in question. We already did but I'd imagine you'll have issues without it.
ingconti is right.
- Upload your app.plist to dropbox.
- Get shared link of app.plist, like https://www.dropbox.com/s/qgknrfngaxazm38/app.plist
- replace
www.dropbox.com
withdl.dropboxusercontent.com
in the link, like https://dl.dropboxusercontent.com/s/qgknrfngaxazm38/app.plist - Remove any parameters on the dropbox shareable link such as "?dl=0t" (as per Carlos Aguirre Tradeco at Enterprise app deployment doesn't work on iOS 7.1 and my own experience).
- Create a
download.html
file with a link formatted as<a href="itms-services://?action=download-manifest&url=https://dl.dropboxusercontent.com/s/qgknrfngaxazm38/app.plist">INSTALL!!</a>
- Upload your
download.html
to dropbox - Again, get a shared link of download.html, like https://www.dropbox.com/s/gnoctp7n9g0l3hx/download.html, and remove any parameters.
- Replace
www.dropbox.com
withdl.dropboxusercontent.com
in the second link as well, like https://dl.dropboxusercontent.com/s/gnoctp7n9g0l3hx/download.html
Now, visit https://dl.dropboxusercontent.com/s/gnoctp7n9g0l3hx/download.html
in your device, you can install the app like before.
WHAT A WONDERFUL WORLD!
Further to the Mark Parnell's answer, a quick-and-dirty way of getting around this is to put the manifest plist into Dropbox, and then using the Dropbox web interface to get a direct https link to it ('Share link' -> 'Get link' -> 'Download').
The actual ipa can remain wherever you always served it from. You'll need to URL-encode the plist's URL before inserting it into the itms-servivces URL's query (although just replacing any &s with %3D might work).
One downside is that the install dialog will now read "dl.dropbox.com wants to install [whatever]".
It is true, going forward you are expected to do all OTA deployments over https going forward with iOS7.1. Shame on Apple for not documenting this.
For those of you that are looking for a better in-house solution than relying on dropbox or having to fork out cash for a certificate you can have a solution if you follow the steps outlined in tip #5 here: http://blog.httpwatch.com/2013/12/12/five-tips-for-using-self-signed-ssl-certificates-with-ios/
The gist of it is this:
- Create your own CA Authority certificate that you can install on the device that is fully trusted (I installed by simply emailing it)
- Create the key/cer pair against the root certificate and install it on your server
- Make sure your webserver utilizes the key/cer pair that matches the CA Authority root certificate
- At this point you should be able to install your apps as usual over https
- All of this can be accomplished on OSX using openssl which is already installed by default
This is not the same as just doing a self-signed certificate, in this solution you are also acting as your own private Certificate Authority. If your root certificate that is installed on your Apple device is not marked as Trusted (green) then something is wrong. Do it over.
This absolutely works.
Update: 3/13/2014 - I have provided a small command line utility that simplifies this entire process. You can get it at: https://github.com/deckarep/EasyCert/releases
I had the same problem and although I was already using an SSL server, simply changing the links to https wasn't working as there was an underlying problem.
Click here for image
That highlighted bit told me that we should be given the option to trust the certificate, but since this is the app store, working through Safari that recovery suggestion just isn't presented.
I wasn't happy with the existing solutions because:
- Some options require dependance on a third party (Dropbox)
- We weren't willing to pay for an SSL certificate
- Free SSL certificates are only a temporary solution.
I finally found a solution by creating a Self Signed Root Certificate Authority and generating our server's SSL certificate using this.
I used Keychain Access and OSX Server, but there are other valid solutions to each step
Creating a Certificate Authority
From what I gather, certificate authorities are used to verify that certificates are genuine. Since we're about to create one ourselves, it's not exactly secure, but it means that you can trust all certificates from a given authority. A list of these authorities is usually included by default in your browsers as these are actually trusted. (GeoTrust Global CA, Verisign etc)
- Open Keychain and use the certificate assistant to create an authority
- Fill in your Certificate Authority Information
- I don't know if it's necessary, but I made the authority trusted.
Generating a Certificate Signing Request
In our case, certificate signing requests are generated by the server admin. Simply it's a file that asks "Can I have a certificate with this information for my site please".
- Next you'll have to create your Certificate Signing Request (I used OSX Server's Certificates manager for this bit
- Fill in your certificate information (Must contain only ascii chars!, thanks @Jasper Blues)
- Save the generate CSR somewhere
Creating the Certificate
Acting as the certificate authority again, it's up to you to decide if the person who sent you the CSR is genuine and they're not pretending to be somebody else. Real authorities have their own ways of doing this, but since you are hopefully quite sure that you are you, your verification should be quite certain :)
- Go back to Keychain Access and open the "Create A Certificate.." option as shown
- Drag in your saved CSR to the box indicated
- Click the "Let me override defaults for this request button"
- I like to increase the validity period.
- For some reason, we have to fill in some information again
- Click continue on this screen
- MAKE SURE YOU CLICK SSL SERVER AUTHENTICATION, this one caused me some headaches.
You can click continue through the rest of the options.
The Mail app will open giving you the chance to send the certificate. Instead of emailing, right click it and save it.
Installing the Certificate
We now need to set up the server to use the certificate we just created for it's SSL traffic.
- If the device your working on is your server, you might find the certificate is already installed.
- If not though, double click the Pending certificate and drag the PEM file that we just saved from the email into the space indicated. (Alternatively, you can export your PEM from keychain if you didn't save it.)
- Update your server to use this new certificate. If you find that the new certificate won't "stick" and keeps reverting, go back to the bit in BOLD ITALIC CAPS
Setting Up Devices
Each device you need to install apps on will need to have a copy of this certificate authority so that they know they can trust SSL certificates from that authority
- Go back to Keychain Access and export your certificate authority as a .cer
- I then put this file on my server with my OTA apps, users can click this link and download the authority certificate. Emailing the certificate directly to users is also a valid option.
- Install the certificate on your device.
Test
-
Make sure your plist links are https
- Try and install an app! It should now work. The certificate authority is trusted and the SSL certificate came from that authority.