Apple was recently in the news, but not for the reason they would normally want to be. A hacking group known as AntiSec published over a million anonymous UDIDs along with device type and usernames associated with the UDIDs. The UDIDs were taken from a an app-publishing company Blue Toad. This episode, along with scrutiny from congress, helps to illustrate why Apple has decided to deprecate the use of UDIDs because of the privacy concerns they created.

A device's UDID is an alphanumeric string that is unique to every Apple device. App developers have been using the UDID to track a user's habits across apps, and potentially sell this information to third party advertisers, and opens up a device to potential malware/spyware attacks. As you can imagine, this practice can cause many privacy concerns for users. In August of 2011 with the release of iOS 5, Apple deprecated the use of UDIDs. They then began rejecting apps that directly access the UDID. Eventually, Apple will completely disable UDIDs.

Since Apple deprecated the use of UDIDs, developers needed a way to generate a unique identifier for their apps. Prior to iOS 6's release, this could be done using the CFUUIDCreate function to create a UUID. To useCFUUIDCreate, you can do something similar to the code below:

CFUUIDRef identifierObject <span class="sy0">=</span> CFUUIDCreate<span class="br0">(</span>kCFAllocatorDefault<span class="br0">)</span>;
 
<span class="co2">// Convert the CFUUID to a string</span>
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span class="kw5">NSString</span></a> <span class="sy0">*</span>identifierString <span class="sy0">=</span> <span class="br0">(</span>__bridge_transfer <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span class="kw5">NSString</span></a> <span class="sy0">*</span><span class="br0">)</span>CFUUIDCreateString<span class="br0">(</span>kCFAllocatorDefault, identifierObject<span class="br0">)</span>;
CFRelease<span class="br0">(</span><span class="br0">(</span>CFTypeRef<span class="br0">)</span> identifierObject<span class="br0">)</span>;

If the identifierString is stored in NSUserDefaults, the newly generated UUID will persist with the application as long as the app is installed on the device. This also prevents the id from being utilized by other applications. Another option would be to store the newly generated UUID in the keychain. This way, if a developer needed to access the UUID across installs of the app, or between apps, it can be retrieved from the keychain. The id can be added to NSUserDefaults with the following code:

<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span class="kw5">NSUserDefaults</span></a> <span class="sy0">*</span>defaults <span class="sy0">=</span> <span class="br0">[</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span class="kw5">NSUserDefaults</span></a> standardUserDefaults<span class="br0">]</span>;
<span class="br0">[</span>defaults setObject<span class="sy0">:</span>identifierString forKey<span class="sy0">:</span><span class="co3">@</span><span class="st0">"udidKey"</span><span class="br0">]</span>;
<span class="br0">[</span>defaults synchronize<span class="br0">]</span>;

The id can then be retrieved with the following code:

<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span class="kw5">NSString</span></a> <span class="sy0">*</span>udidString <span class="sy0">=</span> <span class="br0">[</span>defaults objectForKey<span class="sy0">:</span><span class="co3">@</span><span class="st0">"udidKey"</span><span class="br0">]</span>;

With iOS 6, Apple introduced three new API's to handle unique identifiers and replace the UDID. These new identifiers are Application Identifier, Vendor Identifier, and Advertising Identifier. These three different unique identifiers were designed to handle the various scenarios UDID was previously used for, but in a much more secure manner. With these new identifiers, app developers will have a way to uniquely identify and track users, but won't necessarily allow other app developers to access a users data for another application. Let's delve a little deeper into each of these API's.

Application Identifier

The Application Identifier is a new API introduced with iOS 6 to uniquely identify something. To generate an application identifier and place it in an NSString, you simply make the following call:

<span class="kw4">id</span> appIdObject <span class="sy0">=</span> <span class="br0">[</span>NSUUID UUID<span class="br0">]</span>;
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span class="kw5">NSString</span></a> <span class="sy0">*</span>appIdString <span class="sy0">=</span> <span class="br0">[</span>appIdObject UUIDString<span class="br0">]</span>;

This will generate a unique 128-bit value that contains no hardware details. The value generated will be unique every time the method is called. So now, what will this be used for? The answer is anything. The value generated can then be stored in the NSUserDefaults and retrieved when needed. This means that the application identifier will exist as long as the app is installed on the device, it will be backed up, and can be restored across devices. In other words, it will have the same behavior as every other item in NSUserDefaults.

Vendor Identifier

Vendor Identifier is a unique identifier assigned to each device per development team. A team can be made up of a single developer enrolled in the iOS Developer Program as an individual, or it can be made up of many developers if the user enrolled in the iOS Developer Program as a company. So, once an app is installed on a device for a particular team, there will be a unique identifier generated for each application installed for that team on a given device. This identifier will persist on the device as long as there is an app for that team installed on that device. To access the vendor identifier, simply make the following call:

NSUUID <span class="sy0">*</span>vendorIdObject <span class="sy0">=</span> <span class="br0">[</span><span class="br0">[</span>UIDevice currentDevice<span class="br0">]</span> identifierForVendor<span class="br0">]</span>;

The advantage using vendor identifier over application identifier is that iOS manages the mapping of the identifier, it's backed up, and it will not be restored on a different device (like UDID). This last point means that your vendor id will change across devices. Once a particular team's last app is removed from a device, so is the vendor identifier. This is possible because iOS has a count of applications per team id. A new one will be generated when an app for that team is installed on the device again. One thing to keep in mind, this id is not a hash of the team identifier; it is actually a random id that is generated when a team's first app is stored on the device.

Vendor Identifier Retain Count

Advertising Identifier

The last new API available with iOS 6 is the Advertising Identifier. As the name suggests, this identifier can and should be used for advertising purposes, such as frequency tapping and conversion tracking. In fact, iAd, Apple's advertising network, has converted from UDID to Advertising Identifier exclusively with iOS 6. The advertising identifier is unique to the device and is available to any application. This is the identifier that is most like UDID since it is unique to the device, it is accessible by any application on the device, it is backed up, and it will not be restored onto a different device, like UDID and Vendor Identifier. One difference is that the advertising identifier will be forgotten if a user executes the "Erase All Contents and Settings" action within the settings app. This is possible because the identifier is a software generated identifier, and not a hardware identifier. The advertising identifier can be accessed with the following code:

<span class="co1">#import ;</span>
...
<span class="kw4">id</span> adIdObject <span class="sy0">=</span> <span class="br0">[</span>ASIdentifierManager sharedManager<span class="br0">]</span>.advertisingIdentifier;

Also, the AdSupport.framework must be added to application. This is very similar to how the vendor identifier is accessed. The main difference between vendor and advertising identifier is that vendor identifier is accessible only by the developer of the application and advertising identifier is available to any app by any developer. Users do however have the option of limiting add tracking on their devices. This can be set by selecting Settings ? About ? Advertising. When this is turned to "ON", the advertising identifier can only be used for the following purposes: frequency capping, conversion events, estimating the number of unique users, security and fraud detection, and debugging. This can be checked by calling the advertisingTrackingEnabled method of the ASIdentifierManager class.

Limit Ad Tracking Setting

Comparing The APIs

UDID API Comparison Matrix

Summing It All Up

With iOS 6, Apple has provided these three new APIs that can be used to replace UDID completely with the release of iOS 6. Apple suggests that you begin your transition now. Any new apps you build, should be built using the new APIs. If you have an existing app, transition to the new APIs when you submit updates to the App Store. It is important to do this because UDID and similar identifiers will not be available in the future. The legacy behavior will not change, and any existing applications that are installed will not be affected by this change. Attached is a simple sample project that utilizes these new API's as well as the legacy CFUUIDCreate function.