On March 21, 2013, Apple added an announcement to notify all iOS developers that “using UDID inside the app would no longer be approved by Apple App Store starting from May 1st, 2013”.

Starting May 1, the App Store will no longer accept new apps or app updates that access UDIDs. Please update your apps and servers to associate users with the Vendor or Advertising identifiers introduced in iOS 6.

Reference: Announcement Link

As an alternative, Apple makes a suggestion of using the IDFV (Identifier for Vender) or ADID (Advertising Identifier). It is not an “Mandatory” solution for replacing the using of UDID, in other words, we could still use some 3rd-party solutions such as openUDID or SecureUDID.

However, we would foresee it may become another official standard of iOS in the very near future. Let alone openUDID and secureUDID – the two most popular alternative solutions have announced their retirement.

Now, being an alternative to the FULLY retired UDID, Apple provides not one but two solutions (IDFV and ADID), and we can still use the 3rd-party ones (openUDID, SecureUDID, etc). Apparently, using Apple’s solutions would be the best and safest just because it is from Apple. However, questions may still exists:

  • Can IDFV or ADID fully replace other solutions?
  • For IDFV and ADID, which one should be used and when is it to choose one over the other?

In order to answer these questions, we may need to go through the entire story of UDID on iOS and find out the pros and cons for each alternative. The purpose here is not to make a conclusion on “which one is the best”, but instead, we just want to make a fully understand before we actually go for a solution.

Identify an iOS device

The following table outlines all available (or former available) solutions that are used to “identify an iOS device“.

Methods (Provider)SummaryUsage & Annotation
UDID (Apple)-. The legacy method for getting the “REAL” unique identifier of any iOS device. -. Deprecated since iOS 5, and banned in iOS 7.-. By calling the method: NSString *udid = [[UIDevice currentDevice] uniqueIdentifier];-. In iOS 7, calling the method will return a 40-character string starting with FFFFFFFF, followed by the hex value of getting IDFV: -[UIDevice identifierForVendor]-. String example: bb4d786633053a0b9c0da20d54ea7e38e8776da4
CFUUID (Apple)-. CFUUID has been around since iOS 2.0, which is a part of CoreFoundation package.-. Use the method: CFUUIDCreate. -. Not persist. Every time, calling the method will generate a different string. -. String example:68753A44-4D6F-1226-9C60-0050E4C00067
NSUUID (Apple)-. Introduced sine iOS 6. -. Similar to CFUUID, but a ObjC interface.-. Call the method: NSString *uuid = [[NSUUID UUID] UUIDString];-. Not persist. Every time, calling the method will generate a different string. -. String example:68753A44-4D6F-1226-9C60-0050E4C00067
MAC+MD5 (Unix Syscall)-. Use Unix Syscall to get the “REAL” MAC address of the device, and then use MD5 to generate an string. Since MAC address is unique crossing all devices, the output string is also unique. -. Banned in iOS 7.-. A very concrete method to get a unique identifier for the device, since it never changes since the device being built out. -. In IOS 7, any attempt to getting the MAC address will return a same static value for ALL devices which are running iOS 7.
openUDID (3rd-Pary)-. Generate a unique string based on several sources.-. Store the string to the system’s “Pasteboards”, which can be accessible for ALL apps. -. Also store the string in each app’s sandbox (by NSUserDefault) to increase the persistency. -. Persistency changed in iOS 7.-. The most popular alternative solution since iOS 5. -. Call the method: NSString *openUDID = [OpenUDID value];-. In iOS 7, the “Pasteboards” is on longer being shared within ALL apps. Instead, each “app vender” has individual “Pasteboards”.-. String example:68753A44-4D6F-1226-9C60-0050E4C00067
SecureUDID (3rd-Pary)-. Generate a unique string based on CFUUID. -. Store the string to the system’s “Pasteboards”, which can be accessible for ALL apps. -. Persistency changed in iOS 7.-. In iOS 7, the “Pasteboards” is on longer being shared within ALL apps. Instead, each “app vender” has individual “Pasteboards”.
Identifier for Vendor (IDFV) (Apple)-. Introduced since IOS 6.-. Return an object of NSUUID.-. Call the method: NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; -. The string is the same for apps that come from the same vender on the same device. -. Once all the apps from the same vender are uninstalled and then re-installed, the value will be reset. -. String example:599F9C00-92DC-4B5C-9464-7971F01F8370
Advertiser Identifier (ADID) (Apple)-. Introduced since IOS 6.-. Return an object of NSUUID.-. Call the method: NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];-. Persisted by the system, accessible by ALL apps. -. Can be reset by several “User” operations. -. String example:1E2DFA89-496A-47FD-9941-DF1FC4E6484A

Identifier for Vendor (IDFV)

The unique string generated by this method is “Vender and Device Specific“, which means the value only persists within the apps that come from the same vender on the same device. In other words, a different value will be returned for apps on the same devices that come from a different vender, and for apps on different devices regardless of vender.

A “vender” is defined by the FIRST TWO parts of the reverse DNS formatted CFBundleIdentifier. For example, the bundle identifiers “com.example.app1” and “com.example.app2” will come from the same vender, while “com.anotherexample.app3” will be the different.

Advertiser Identifier (ADID)

The value generated by this method can be persisted across the whole system, which means any app on the same device will get the same value. However, the persistency of this value can be easily affected by many “user” operations:

  • System Reset – path: Settings.app -> General -> Reset -> Reset All Content and Settings
  • Reset ADID – pat: Settings.app -> General -> About -> Advertising -> Reset Advertising Identifier (iOS 7: Settings.app -> Privacy -> Advertising -> Reset Advertising Identifier)

openUDID

When openUDID is released, it is designed for providing a UDID-like “device wide” unique identifier, which means that this identifier will be shared across all apps that use openUDID method.

Here are some technical highlights of openUDID:

  • A 160-bit ID – the first 128 bits are a MD5 on the result of [NSProcessInfo -globallyUniqueString]; the latter 32 bits are from the output of arc4random().
  • Use UIPasteboard to store the ID.
  • In UIPasteboard, it uses 100 custom pasteboard items, named “org.OpenUDID.slot.N”, where N is [0, 99].
  • Each app picks one of the 100 slots (save the choice locally in NSUserDefaults), and saves the current openUDID inside it. If the app does not have from its local preference, it will go through all 100 slots and choose the UDID that is represented most frequently.
  • If all slots are empty, it will generate a new openUDID.

SecureUDID

Although SecureUDID uses the similar technique as openUDID to store the identifier and share it within apps on the device – UIPasteboard, it is designed with some security related goals – where is also the name from.

Instead of sharing the ID across all apps on the device, it is only accessible for the apps that share the same “secret” – a crypto key used to encrypt the ID before storing back to UIPasteboard.

Here are some technical highlights of SecureUDID:

  • Use UIPasteboard to store the ID – 64 slots (“org.secureudid-N”, where N is [0, 63]) to store the ID as well as some metadata.
  • A 128-bit ID, generated by CFUUIDCreate().
  • The “secret” is a SHA1 hash of the concatenation of two values – a domain string and a private key.

Limitations of using UIPasteboard based UDID Frameworks

Although openUDID, SecureUDID or any other UIPasteboard based UDID Frameworks
can provide certain level of persistency in the device-specific ID, this persistency cannot be guaranteed in all situations. It is technically possible for two different devices to generate the same ID, and for the same device to generate different IDs.

Here are some typical situations that may affect the uniqueness / persistency of the ID:

  • The user / other app opts-out of the system (explicitly or implicitly).
  • Once device is backed up and then restored to another device.
  • The data stored in UIPasteboard is removed / corrupted by user intervention, UIPasteboard data purge, or by a malicious application.
  • All apps that use the UDID framework are uninstalled from a device, right after a UIPasteboard data purge.

Changes since iOS 7

Although using the “REAL” device UDID has been deprecated since iOS 5, the actual API is still working correctly. Apple only does a “policy enforcement” on the apps that need to be available on the Apple App Store.

However when iOS 7 comes, it has been changed, not only for the device UDID retrieval but also for the using of MAC address as well as all UIPasteboard based UDID Frameworks.

  • The API for getting device UDID becomes malfunctioning – it returns a 40-character string starting with FFFFFFFF, followed by the hex value of getting IDFV: [UIDevice identifierForVendor] instead of a real device UDID.
  • The method for getting MAC address returns a same value for ALL devices that run iOS 7.
  • Pasteboards will be ONLY shared within the apps that come from the same vender, not ALL apps on the device.

Based on the third change, it becomes impossible for using UIPasteboard based UDID Frameworks (openUDID or seCureUDID) to generate a unique ID that represents the device.

However, you can still use them to create the ID to distinguish the different user of the same app running on the different devices because of its uniqueness / persistency. But, the point is, “IDFV” can also achieve that. Then, is there any reason of still using these 3rd-party solutions, without choosing an Apple one?

Comparison and Conclusion

The following tables provide a clear view on the iOS availability and persistency of these methods:

iOS Availability

MethodsiOS 2iOS 3iOS 4iOS 5iOS 6iOS 7
UDIDX
MAC+MD5X
CFUUID
NSUUIDXXXX
IDFVXXXX
ADIDXXXX
OpenUDID?
SecureUDID?

Persistency

MethodsLaunch AppReturn from BackgroundReset Advertising Identifier [1]Re-install App [2]Reboot System [3]Reset System [4]Upgrade SystemRe-install System
UDID
MAC+MD5
CFUUIDXXXXXXXX
NSUUIDXXXXXXXX
IDFVXX?√?X
ADIDXX?√?X
OpenUDIDX?√?X
SecureUDIDXX?√?X

Here are the legends & annotations:

  • √ – YES
  • X – NO
  • ? – TBD

[1] – Reset Advertising Identifier | Settings.app -> General -> About -> Advertising -> Reset Advertising Identifier (iOS 7: Settings.app -> Privacy -> Advertising -> Reset Advertising Identifier).

[2] – Re-install App | Remove all apps that come from the same vender before the re-installation.

[3] – Reboot System | Hold on “Home” and “Power” buttons.

[4] – Reset System | Settings.app -> General -> Reset -> Reset All Content and Settings

For the actions of “System Upgrade” and “System Re-install”, currently we still have not found a concrete way to test on the real devices. So far, it is only under a guess. Especially, the “System Upgrade” can be done either on the air or via iTunes, which may have a different consequence.


References:

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>