In my previous article Get the device ID in iOS 6.0 and earlier I used [[UIDevice currentDevice] uniqueIdentifier]
to retrieve a unique identifier for the user device when the current iOS version is 5.x or older.
But uniqueIdentifier
method cannot be used anymore on Apple App Store apps. As mentioned by other developers (see MKStoreKit discussion on uniqueIdentifier and Stackoverflow identifierforvendor discussion) Apple added an automatic check which rejects all apps using this method. Moreover in iOS7 Apple removed uniqueIdentifier
method.
Unfortunately Apple forces applications to remove the ability to get the UDID for privacy reasons. A universal identifier able to identify the device without requiring authorization from the user may allow to collect usage information from different applications and relate them to build a user profile based on applications usage (for example a third party vendor may buy informations from different app vendors…).
The following implementation avoids using uniqueIdentifier
method in iOS 5.x or below.
- For iOS6.0 or later I use the
identifierForVendor
new method. - For iOS5.x or below I use
CFUUIDCreate
method in association with storage intoNSUserDefaults
.
The second method will not ensure to have a unique identifier if the application is deleted and reinstalled.
You have to replace the @"app identifier"
with your app identifier. The code uses ARC for memory management.
// Get the device id on iOS7.0 and previous versions - (NSString *) getDeviceId { NSString *deviceID; UIDevice *device = [UIDevice currentDevice]; if ([UIDevice instancesRespondToSelector:@selector(identifierForVendor)]) { deviceID = [[device identifierForVendor] UUIDString]; } else { // In iOS5.x or older 'identifierForVendor' is not available deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"app identifier"]; if (!deviceID) { CFUUIDRef uuidRef = CFUUIDCreate(NULL); CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef); deviceID = [NSString stringWithString:(NSString *) CFBridgingRelease(uuidStringRef)]; CFRelease(uuidRef); [[NSUserDefaults standardUserDefaults] setObject:deviceID forKey:@"app identifier"]; [[NSUserDefaults standardUserDefaults] synchronize]; } } return deviceID; }
Tip: CFUUIDCreate
and CFUUIDCreateString
functions are Core Foundation functions that follows the Create Rule. So the uuidRef
must be released with CFRelease
whereas the uuidStringRef
ownership is transferred to ARC with CFBridgingRelease
and CFRelease
is not needed.