UIDevice currentDevice identifierForVendor - can this change on an iPad - ios

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.

Related

How to get advertising identifier on IOS

I'm doing Work light Project, and i need a plugin to get advertising identifier, which value not change unless user hard reset them phone.
But because i'm never do IOS before, so i don't know how to get advertising identifier on IOS 6,7.
I was try identifierForVendor, but it change everytime i reinstall an application.
Any help for me ? (i do not need push this app to appstore).
To get AdvertisingId of any iOS Device do this :
Only for iOS versions > 6.0
#import <AdSupport/ASIdentifierManager.h>
NSUUID *adId = [[ASIdentifierManager sharedManager] advertisingIdentifier];
NSString *str = [adId UUIDString];
Did you try to use advertisingIdentifier?
If you check the documentation
https://developer.apple.com/Library/ios/documentation/AdSupport/Reference/ASIdentifierManager_Ref/ASIdentifierManager.html#//apple_ref/doc/uid/TP40012654-CH1-SW4
Unlike the identifierForVendor property of the UIDevice, the same value is returned to all vendors. This identifier may change—for example, if the user erases the device—so you should not cache it. If the value is nil, wait and get the value again later. This happens, for example, after the device has been restarted but before the user has unlocked the device.

Uniquely Identify iOS device over multiple users

I have done a lot of research on this so please read the question before marking this as similar to some other question.
Our app needs to uniquely determine an iPhone such that even when user completely wipes a phone, when he runs our app we can be sure that it is the same device. The most important thing is we also need to determine devices over multiple Apple ID users so suggestions containing Keychain access and uniqueVendorID might not work as those change when another user starts using that phone. And as I have read using MAC addresses and old UDID for devices is not longer available as of iOS 6.0. I went through [UIDevice identifierForVendor] but this NSUUID changes when all the app by the same vendor has been uninstalled Reference.
I have looked through these resources:
UIDevice uniqueIdentifier Deprecated - What To Do Now?
and
What is a long-term method I can use to uniquely identify an iOS device?
I can not disclose the nature of work that my app performs due to non-disclosure, but to clarify what I require:
Multiple users might use our app on same phones, I need a way to know that the device user A used before and has reported to have handed over to user B is the same device on which our app was run. Is there any way to achieve this?
There's no way to achieve this.
If it's really the case that different users might use your app on the same device after a factory reset of the device, then what you want is not possible. Apple deprecated UIDevice uniqueIdentifier which would have been the way to do this.
as long as they dont restore/wipe the device identifierForVendor is ok

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

iPhone/iPad unique identifier BESIDES UUID/UDID?

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.

Resources