There is a lot of buzz with Apple’s rejection of apps accessing UDID API . Let us analyze it.
What is UDID?
UDID is the unique identifier to identify an iOS device uniquely. Apple had exposed an API to access this unique identifier from the start of iOS 2.0 SDK. This made interesting things possible and eventually became a critical API for some of the application’s core functionality. For example. Flurry Analytics, depend on this UDID for reporting number of devices an application is activated. Although, I cannot go through all the list of application using this API, let us do some Impact Analysis and possible problems and their solutions from this move by Apple.
When would you use the uniqueIdentifier?
I would typically use it in the context where I need to uniquely identify the device in a pool of iOS devices, where this info is send to a centralized place and is used for various purposes. Standalone applications more often does not need this info, unless they have integrated with third party SDK like Flurry, to support non-core features of an application, such as gathering statistics. Therefore, we would not keep this category of applications as these does not have major dependency on UDID.
What would you do with uniqueIdentifier with a pool of device?
“A scenario could be where the application could act as client and all the instances of the application across the devices are writing some data into the centralized place, could be a Mac or a Centralized Server. In this case the unique identifier would be able to identify the application instance uniquely to resolve the conflicts, say while writing the data to same location.”
Fig: Scenario 1 showing Application installed in multiple iOS devices syncs with Mac / Server sharing and updating the data
Example: A Simple Notes application where notes are recorded in various iOS devices and then are synchronized with the Mac Application, where the Mac Application acting as a centralized unit.
“Another scenario would be to individually track the number of devices in which the application is activated which helps the sales people to pitch up their sales or we can find them in many of the third party ads which aid in gaining statistics of the application”
Example: Analytics SDK like Flurry, InMobi and so on.
While the first scenario helps the application in its core functionality, the second scenario is matter of statistics that helps drive the sales. However, accessing a unique identifier of a device without knowledge is a breach of privacy which i believe the motive behind apple deprecating this API.
Before digging deep, Let us look at the alternative solution from Apple?
Do not use the uniqueIdentifier property. To create a unique identifier specific to your app, you can call the CFUUIDCreate function to create a UUID, and write it to the defaults database using the NSUserDefaults class.
Well, CFUUIDCreate does create the unique identifier, but will that be sufficient to identify the Device uniquely?? Wait, am I sounding wrong! Your read it right.
Although Apple recommend to create unique identifier and store it in defaults, it works fine as long as the app isn’t deleted and re-installed by the user. Since, doing that would delete the defaults database and upon re-installing a fresh unique identifier would be created which defeats our purpose.
Let us track back and see what exactly we need
“We need to find a way where an application would identify uniquely against its clone across multiple devices.”
The critical requirement here is not creating a unique identifier, but persisting it from the time application is installed on a device till literally the lifetime of the device and not the application. Uh!!
There are many solutions floating around like the one from crashlytics, where they achieve the persistence by storing the custom unique identifier in the UIPasteboard. However, there are couple of cons here
- Apple does not guarantee that the Pasteboard data persists permanently across OS upgrades or reboot
- Any other application can access this data or override them and one need to ensure that this would be in un-readable form for other that the application which created it.
My Solution (Intermediate):
The solution is to change the way we modelled our application behavior. For you to understand, let me divide the iOS era into two.
Pre-iCloud & Post-iCloud.
In Pre-iCloud we used to treat each iOS device as a separate one even though they are owned by ( literally under same apple id) single person. This means that an app in iPhone would have different state than the one in iPad, and probably a External Sync would be required to get them into single state.
In Post-iCloud era, as a developer, one should not distinguish between an application installed in two iOS device grouped under single Apple ID, which is strong point behind the Apple’s iCloud – “It Just Works”. i.e the iCloud make sure that all the data and state information would be consisted across the iOS devices grouped under single Apple ID.
With that differentiation, the solution would be:
“Create a unique identifier as suggested by the Apple and store them in defaults as wells as in iCloud. Check NSUbiquitousKeyValueStore or using this short piece of library from Mugunth Kumar which I liked, for storing into iCloud. So Even if the App is deleted, the same ID would be retrieved back from iCloud, unless your iCloud is reset which accom”
NOTE: We could use a same approach for tracking the number of apps installed with the difference being the count would be number of users installed the application rather than the number of devices using it.
What are your thoughts on this?