Getting your app into beta tester’s hands is a pain. Even with new services like Test Flight the process is confusing and clunky for testers because the user has to login & it’s not entirely clear to the user what is going on.
The problem is, you need the person’s UDID & they have no idea what it is or how to find it.
Overview of Getting a UDID through Mobile Safari
Apple allows developers to get a person’s UDID (& do many other things) through a special interaction between the phone and your web server. Here’s an overview:
- They click a link to a .mobileconfig XML file on your website
- This pulls up their provisioning settings on their phone & offers them an ‘Install’ button (which they must press)
- The phone sends the data you requested in encrypted XML to the URL you set in your .mobileconfig
- You process the resulting data & show them a “thank you” web page
1) Your .mobileconifg
In this article I’m focused on getting a UDID. You can do many other things, but here is an example configuration for getting the UDID.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>PayloadContent</key> <dict> <key>URL</key> <string>http://yourwebsite.com/retrieve.php</string> <key>DeviceAttributes</key> <array> <string>UDID</string> <string>IMEI</string> <string>ICCID</string> <string>VERSION</string> <string>PRODUCT</string> </array> </dict> <key>PayloadOrganization</key> <string>yourwebsite.com</string> <key>PayloadDisplayName</key> <string>Profile Service</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadUUID</key> <string>9CF421B3-9853-4454-BC8A-982CBD3C907C</string> <key>PayloadIdentifier</key> <string>com.yourwebsite.profile-service</string> <key>PayloadDescription</key> <string>This temporary profile will be used to find and display your current device's UDID.</string> <key>PayloadType</key> <string>Profile Service</string> </dict> </plist>
You’ll need to fill in your own URL and PayloadUUID. The PayloadUUID doesn’t have to be generated in a special way – just make sure it is unique to your app.
Also make sure to register a file handler for .mobileconfig (content type application/x-apple-aspen-config).
2) The User Views Your Provision Profile
PayloadOrganization and PayloadDescription are shown to the user when they see the profile. In my description, I said something like “Press Install to continue…” since they may be confused on this screen.
You don’t have to sign your .mobileconfig, but if you don’t then they will see a warning that it is not signed (see below).
3) Receiving the Requested Data
QUIRK WARNING: For whatever reason, the process is EXTREMELY particulary about how your server responds when it sends the user to your preset URL. After many tries, I believe that your receiving url MUST be a .php file. This sounds nuts but I’m serious.
PHP was about the last language I wanted to work in, so I chose to redirect to a page that could handle it better.
<?php $data = file_get_contents('php://input'); header("Location: http://www.mysite.com/Results?data=".rawurlencode($data)); ?>
QUIRK WARNING:: The only way I (& others) have got it working is to redirect to a directory. I’ve tried to redirect to a .aspx page and it failed. If you do not get this right, then a vague error message will be shown to the user & they will be stuck. If you have a better explaination for this, please leave a comment below.
The page that you redirect to is the page that is shown to the user to end the process.
In my example, that page would receive a ‘data’ query string parameter containing the xml response from the phone.
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>IMEI</key> <string>12 123456 123456 7</string> <key>PRODUCT</key> <string>iPhone4,1</string> <key>UDID</key> <string>b59769e6c28b73b1195009d4b21cXXXXXXXXXXXX</string> <key>VERSION</key> <string>9B206</string> </dict> </plist>