iPhone/iPad unique identifier BESIDES UUID/UDID? - ios

The project I am on is requesting two (or even three) unique identifiers from the iPhone or iPad. I know, I know... the UDID should be enough but we are trying to see if there are any other unique identifiers that we can use.
I can get the IMEI, serial number, MAC Address, etc. from the phone using the IOKit.framework but apparently this is frowned upon by Apple and any app using this framework will be rejected.
Does anyone have any other ideas, or identifiers that I am missing that could be used?
Thanks!

This question is old however a new unique, vendor based, identifier has now been added to replace the deprecated UUID in iOS 6.
The [UIDevice identifierForVendor] should now be used instead of [UIDevice uniqueIdentifier] which is now deprecated as of iOS 5.0
Example usage:
NSUUID *uuid = [[UIDevice currentDevice] identifierForVendor];
NSString *uuidString = [uuid UUIDString];

You can get the ICCID and the IMSI (if they exist).
NSString *commcenter = #"/private/var/wireless/Library/Preferences/com.apple.commcenter.plist";
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:commcenter];
NSString *ICCID = [dict valueForKey:#"ICCID"];
NSString *IMSI = [dict valueForKey:#"IMSI"];
I think that's as far as you will get. I don't know any other options for getting an universal ID.
UPDATE 2013-03-13:
This has probably changed since I wrote this answer almost two years ago. I don't even remember what was the iOS version at the moment. Also as #joshis correctly pointed out in the comments "You cannot legally do this, since your app would read stuff from outside the application sandbox and therefore, it will be rejected, as specified in AppStore Review Guidelines...".

From Apple:
The value in this property remains the same while the app (or another
app from the same vendor) is installed on the iOS device. The value
changes when the user deletes all of that vendor’s apps from the
device and subsequently reinstalls one or more of them.
So if you use [UIDevice identifierForVendor] and the user delete the app and reinstall it, the id will be different(so no real physical device tracking)
Why don't you use SecureUDID?
NSString *domain = #"com.example.app";
NSString *key = #"mykey";
NSString *udid = [SecureUDID UDIDForDomain:domain usingKey:key];
This way, even if the user delete the app and reinstall it, the UDID will be same. This will give you consistent tracking(or whatever you want to do with the UDID).
Btw, the above is still permitted from Apple.
Have fun.

The method for getting the UDID is being deprecated, you should now use CFUUIDCreate which I think could be used multiple times to get more identifiers if needed

Perhaps you should clarify your question.
requesting two (or even three) unique identifiers from the iPhone or iPad
…is a contradiction in terms. If your purpose is to track a specific physical device, then a single unique identifier, by definition, is enough. That’s what unique means.
Perhaps, what you really want is to track multiple things about each user’s use of your app, as opposed to the device. Say your networked game app allows the user 1, 2, or 3 different personalities. As they user creates a distinct personality, you must track each of that user's personalities amongst all the other user’s personalities.
For this kind of purpose, generating and storing a UUID* is a proper and common solution. iOS includes libraries to generate a UUID value. The only catch is that if the user deletes and re-installs the app, the storage of that UUID may be lost. There are workarounds for this challenge, which you may learn about by googling for discussions of replacing UDID tracking with generated UUID values.
This question is a bit older. So I should mention: In iOS 5, Apple deprecated the use of the UDID. As of 2013-05-01 Apple is rejecting any app that accesses the UDID.
(*) Do not confuse a UUID with a UDID. UUID is a standard 128-bit (32 hex digits) number often used as a virtually unique identifier in many technology scenarios. UDID is Apple's 40 hex digit string burned into every iOS device to uniquely identify each device.

DeviceCheck API in iOS 11 is an interesting solution to get unique Identifier, the advantage it has is - the value will be retained even after the app in uninstalled. So use cases like trial installation and rewards can be effectively controlled by developers.

Related

Best way to uniquely identify iOS device?

I'm aware if the following methods, each which has it'd flaws
UDID
Advertising Identifier
Vendor ID
The problem with UDID is that its deprecated and doesn't even work as of ios7, problem with other two is that the user can change them via software reset of phone or reinstallation of app
Another interesting solution I found is to randomly generate one yourself and then save to keychain to avoid deletion upon app reinstallation however would this work across software resets? And surely there's a very small chance that two devices would randomly generate the same ID?
I think the best option might be to use UDID but I would like to know if, even though the UDID is incorrect as of ios7, is it still unique?
Yet another option is MAC address but as far as I know, there is no API for these
Please advise on the best option
Starting iOS 7 deducing MAC address isn't possible. You can, however, use below:
[[[UIDevice currentDevice] identifierForVendor] UUIDString]
Per Apple Documentation:
The value changes when the user deletes all of that vendor’s apps from
the device and subsequently reinstalls one or more of them. The value
can also when installing test builds using Xcode or when installing an
app on a device using ad-hoc distribution. Therefore, if your app
stores the value of this property anywhere, you should gracefully
handle situations where the identifier changes.

UIDevice currentDevice identifierForVendor - can this change on an iPad

My app uses UIDevice currentDevice identifierForVendor to help me identify the device. Recently I have encountered a situation that I can't understand. A UIDevice currentDevice identifierForVendor of an iPad of one of my clients seems to have changed. Is this ever possible?
UIDevice Class Reference say :
The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them. The value can also change when installing test builds using Xcode or when installing an app on a device using ad-hoc distribution. Therefore, if your app stores the value of this property anywhere, you should gracefully handle situations where the identifier changes.
You can use KeyChain to store something unique as UUID(Create by your own method or use API). This may be helpful for you.
UIDevice currentDevice simply returns information about the currently running device. Within that there are several properties you can check. I assume you are checking [UIDevice currentDevice] identifierForVendor] If that is the case, YES it can change. If the user deletes your app AND all other apps created by you (the app vendor) then the identifierForVendor can change. Another case where it can change is if it was not installed from the App Store and then later is. For example, you give your client an ad-hoc build to test and then later they install the real app from the App Store.
Another solution I found while searching for an unique and fixed ID for an "almost" consistently/fixed ID is to use the advertisingIdentifier. You can check the ASIdentifierManager. To have access to the ID you need just this:
#import AdSupport
...
NSString *id = [[ASIdentifierManager sharedManager] advertisingIdentifier];
This ID will be reset if the device has his settings reseted or his advertising identifier reseted.
Currently I'm sticking with the creation of a new UUID using
NSString *UUID = [[NSUUID UUID] UUIDString];
and storing it somewhere.
There appears to be a bug that surfaced around the end of May that causes identifierForVendor to return a new identifier after a user updates the app in the App Store, when according to the documentation it should return the same identifier. See these and these Apple developer forum posts. I've seen this too and it affects about 20% of my users.
[UIDevice currentDevice] is not an identifier. It's an instance of a class. I assume you mean identifierForVendor, which is unique but not fixed.
The documentation is fairly helpful to understanding it, as well as providing alternatives. One that isn't listed is the device token for push notifications, but that's a whole different bag which you many not want to get into.

Finding IMEI number using Objective-C [duplicate]

This question already has answers here:
How to get IMEI on iPhone?
(7 answers)
Closed 2 years ago.
I need to find a way to get the IMEI number of an iPhone device. This question is not a duplicate.
I have gone through several forums including SO, and had no luck finding an answer.
Some say Apple doesn't allow developers to see the IMEI number (SO post), and some say to use UDID instead (SO post). Some say that UDID is deprecated (in iOS 7).
I need to know the following:
1.) Does Apple permit developers to retrieve the IMEI number of the device?
2.) How can i programatically do it?
3.) In case if Apple doesn't allow developers to gather the IMEI number, do they provide any other unique number for the device?
4.) Some suggest to use Telephony framework. If i do so, will apple reject my application?
Apple does not allow you to identify a device any more.
UDID, MAC address and all other device identifiers are no longer accessible or allowed by Apple.
Apple suggest that you use either UUID (which you will need to store your self or), identifierForVendor or advertisingIdentifier.
Apple is now also rejecting app that use the advertisingIdentifier and not showing any advertisements apps.
Any means to get the IMEI number are using private methods, which is also not allowed by Apple anymore. And your mobile app might/will get rejected because of this.
Unfortunately, there is no way to get a unique identifier for a device which will always remain the same. Apple no longer allows you to access the UDID. And in iOS 7, all devices' MAC addresses return the same value, so that is no longer useful either.
However, iOS does now give access to two types of identifiers which can be used to identify a device. They are:
Vendor ID - [UIDevice identifierForVendor]. This is a unique identifier which is the same for all apps from the same vendor or company. It will remain the same, so long as the user has at least one app from the vendor installed on their device. So if you have 3 apps, the vendor ID will remain the same unless the user uninstalls all three apps, and then reinstalls. This is not so useful if you only have one app - if the user deletes it and then reinstalls it, it will change.
Advertiser ID - [UIDevice advertisingIdentifier]. This is a unique identifier meant for advertising purposes. But if you use it for non-advertising purposes they, for the most part, won't care. Under most circumstances, the advertising identifier will not change, even if the user deletes and reinstalls the app. However, there is an option in the iOS settings to reset the advertising identifier, which will change it. This is meant to that users can choose to disassociate themselves from any advertising information which has been collected about them. But this is a very advanced setting and I doubt that many users would do this frequently enough that it would be a problem for you.
You can obtain IMEI using private frameworks -See this Question but probably your app will be rejected from app store then.
If you want to obtain some device identifier to use in your application you must use uniqueIdentifier property defined in UIDevice class
(Available in iOS 6.0 and later):
NSString *UDID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
You can save UUID in keychain and user it as unique number. It won't change until user will reset iOS.
If you want to obtain the IMEI there is no way (on a non-jailbroken device). If you wish to identify the user take a look at this answer. Please pay attention to all documentation/answers written before iOS7 since things have changed.

Alternative way to create lifetime unique id

I want to create UDID for iphone/ipad device which will remain unchanged, so please tell me if any one have idea for that?
I have search around google and stack-overflow, but not got solution.
Also some suggested to use OpenUDID and CFUUID, but CFUUID will be different when users delete and reinstall your app. But i want to use same UDID per application which will generated at first time and should remain unchanged for lifetime per device for each application.
EDIT 2
Because of iOS upgrade and as per new documentation identifierForVendor does not retain value on app re-installs. I have seen answer at this link. This may help in one or other way. Just to note only UDID will retain even if system reset, So probably this answer can become limitation for developers seeking for lifetime UDID even on system reset. Other than this, mentioned answer seems useful.
Also look the summary here.
identifierForVendor is available from UIDevice Class Reference.
The value of this property is the same for apps that come from the
same vendor running on the same device.
[[UIDevice currentDevice] identifierForVendor].UUIDString
Note: Available in iOS 6.0 and later.
EDIT 1 As per new release of UIDevice Class Reference
The value in this property remains the same while the app (or another
app from the same vendor) is installed on the iOS device. The value
changes when the user deletes all of that vendor’s apps from the
device and subsequently reinstalls one or more of them. Therefore, if
your app stores the value of this property anywhere, you should
gracefully handle situations where the identifier changes.
EDIT
I would like you to see at this popular link
1) MD5 of MAC+CFBundleIdentifier
[[UIDevice currentDevice] uniqueDeviceIdentifier]
This will remain same per app but different for each app. If you delete and reinstall your app it will be same per app.
2) MD5 of the MAC
[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]
This will remain same for all app from same device. If you delete and reinstall your app it will be same per device.
EDIT 3
Note: This solution in iOS 7 is no longer useful as uniqueIdentifier is no longer available from iOS7.
Its important to note the difference between a UDID and a UUID.
UDID "unique device id" is hardware specific. It never changes for a particular device. For this reason, it has become a privacy concern and Apple is blocking apps that try to use this. As a result, Apple has generated an opt-out-able "device id" hash, particularly for advertisement usage. This new ID hash is called IFA and is available in iOS 6.0+.
UUID "universally unique id" is not hardware specific. It is a hash used to identify a device; but not particularly an absolute value. For example, PhoneGap generates a UUID based on device properties; this is what you get when you do device.uuid. If you delete the app and reinstall, you will get a new id hash. UUID is not being blocked by Apple.
I think the best solution is to use the IFA, with OpenUDID as a backup for iOS < 6.0.
Here is the code we use. If IFA is not available, get OpenUDID. [[You must install OpenUDID, read more about that here, https://github.com/ylechelle/OpenUDID.]]
NSString* uuid = nil;
if ([[UIDevice currentDevice] respondsToSelector:#selector(identifierForVendor)]) {
// IOS 6 new Unique Identifier implementation, IFA
uuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else {
// Before iOS6 (or if IFA disabled) you shoud use a custom implementation for uuid
// Here I use OpenUDID (you have to import it into your project)
// https://github.com/ylechelle/OpenUDID
NSString* openUDID = [OpenUDID value];
uuid = [OpenUDID value];
}
Generate an UUID (using the CFUUIDRef API, perhaps) for the first time, and store it in the keychain.

iOS6 UDID - What advantages does identifierForVendor have over identifierForAdvertising?

Apple is changing their privacy settings for iOS6 and deprecating device UUIDs (UDIDs). According to a WWDC presentation and the docs there are two replacements for the UDIDs, both in the UIDevice class:
-identifierForVendor
ID that is identical between apps from the same developer.
Erased with removal of the last app for that Team ID.
Backed up.
-identifierForAdvertising
Unique to the device.
Available to all applications; used for advertising — iAd has converted from UDID for iOS 6 and later.
Reset with "Erase All Content & Settings".
Backed up.
It seems to me that -identifierForVendor is inferior to -identifierForAdvertising since it would get reset on last uninstall of an app from a vendor and by "erase all contents & settings".
What advantages does -identifierForVendor have over -identifierForAdvertising?
Important Note:
Apple just released iOS 6.0 and the NDA has been lifted.
For developers who preemptively included code that referenced
[[UIDevice currentDevice] identifierForAdvertising]
this method has NOT been included on iOS 6. If you use the above method, your app will (most likely) crash and be rejected!
Instead, Apple has created a new class ASIdentifierManager , which includes the method advertisingIdentifier. Here's the apple docs on it:
Users can limit the use of ad tracking on their phone. See this article on the opt-out mechanism under Settings > General > About > Advertising.
The new ASIdentifierManager class has a property advertisingTrackingEnabled, which returns true or false depending if the user has limited ad tracking. Even though the device's advertising identifier is returned by the advertisingIdentifier property regardless of opt-out, you aren't supposed to use the identifier if the user has opted-out.
So the advantage of identifierForVendor is that you'll always have access to and the right to use this id for the phone regardless of user's opt-in or opt-out for advertising tracking.
I suspect that Apple will simply reject your app if you use identifierForAdvertising for anything that is not advertising-related (i.e., if you send the identifierForAdvertising to your own servers even though you're not an advertising network or if you send the identifierForAdvertising in the same request with other data that could potentially identify an individual).
If my suspicion is correct, the advantage of identifierForVendor over identifierForAdvertising is that it won't get your app rejected.
They are two different ids meant for two different purposes.
I would think that the identifierForVendor would be the one to use to do things that require the app linking to a specific user / device such as provide push notifications and updating the user's app data serverside (like their score or whatever other data is being stored for them).
The identifierForAdvertising should be used for things such as targeted advertising and also to check the effectiveness of a particular ad campaign (check to see which devices installed apps due to a particular ad).
Use the VendorID.
This is a very enlightening article http://www.doubleencore.com/2013/04/unique-identifiers/
To create a uniqueString based on unique identifier of device in iOS 6:
#import <AdSupport/ASIdentifierManager.h>
NSString *uniqueString = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSLog(#"uniqueString: %#", uniqueString);
Those APIs are so badly designed, that clearly says - Apple does not want us to identify user devices.
Just look at the identifierForVendor description.
It is erased if the user erases all apps from the same vendor. :(
It is not reliable - can return nil (documentation advices to "wait" for some time if this happens. :(
They did not use obvious solution, which works anytime and does not rely on installs/removes - return SHA-1 (or any other hash) of internal hardware device id concatenated with Team ID.
identifierForAdvertising is probably superior in terms of tracking but might be subject to present or future opt-out by the user. On the other hand identifierForVendor is not as likely to be subject of the user.
The important thing to know is that the backup of the identifierForVendor can only be restored to the same device. If the backup is restored to a difference device the identifier is cleared.
User can change identifierForAdvertising any time in Settings,
identifierForVendor changes after reinstall app, if no more apps on device from this vendor.
Here is alternative and the best solution for get or persistent, cross-install Device Identifier:
description: https://blog.onliquid.com/persistent-device-unique-identifier-ios-keychain/
code: https://gist.github.com/miguelcma/e8f291e54b025815ca46

Resources