How can I uniquely identify iPhone/iPad? - ios

I am trying to uniquely identify the iPhone/iPad mobile devices to save user data.
I found out some, including
[NSString *UUID = [[NSUUID UUID] UUIDString];
[UIDevice currentDevice].identifierForVendor.UUIDString;
or take device token from
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{ ... }
But the problem is that
UUID changes everytime I close and restart the app (I experienced
from debugging)
identiferForVendor changes every time I delete and reinstall the app
(or update the app)
I used device token to uniquely identify device across version
updates, reinstall, but I learnt that it can be changed, and I am
experiencing it from my updates and debugging in xCode.
Since app store rejects using uniqueIdentifer, my question here is:
Is there any way we can uniquely identify devices across any application updates, deletion, reinstallation?

Use SSkeychain to store unique key permanently. Take 4 files from sskeychain folder from this github example into your project
then after use this code to get unique identifier.
-(NSString *)getUniqueDeviceIdentifierAsString
{
NSString *appName=[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
NSString *strApplicationUUID = [SSKeychain passwordForService:appName account:#"incoding"];
if (strApplicationUUID == nil)
{
strApplicationUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[SSKeychain setPassword:strApplicationUUID forService:appName account:#"incoding"];
}
return strApplicationUUID;
}
This identifier will not change after deleting and reinstalling app. I have used this and it is working perfect for me.

The closest thing I can think of is generating your own UUID and storing it in the device keychain.
By doing this, it will survive app deletion/reinstall, and if the user has enabled iCloud Keychain, it should also survive a device restore.
To make things easier, you can use a keychain wrapper among the many available as open source (one is here).

There's a great posting about this.
http://www.doubleencore.com/2013/04/unique-identifiers/

One creative method might be the possibility of (ab)using the MAC address of the wifi port.

Related

Check if an ios device was blocked [duplicate]

This question already has answers here:
UIDevice uniqueIdentifier deprecated - What to do now?
(32 answers)
How to preserve identifierForVendor in ios after uninstalling ios app on device?
(8 answers)
Closed 4 years ago.
Is there a way to identify a device which was blocked by my app, so they cannot create a second account?
I have read a little bit about Unique Identification and DeviceCheck, Apple's own IPA. I also considered to ask for the phone number when the user signs up, but this seems a little complicated for me and the other solutions only work if the user is kind enough no to reinstall the app.
On other approach I had was to get some information (Carrier, iPhone Name, iOS Version, iPhone Model etc.), pack it into one String and use it as an unique id, but some of this information can be changed easily and I don't think Apple would like this solution.
I am sure that there are better/simpler solutions.
(This task seems very easy in Android. I plan to use this statement: UUID.randomUUID().toString();)
That info could help:
I am planning to connect this app to Firebase.
In the best case, the solution would work from iOS 8.0 to the current iOS Version.
I am open for any kind of creative solution in Swift or Objective C.
We can achieve this by using SSKeychain. Using SSKeychain once we have set value for particular in the SSkeychain then that value will remain their even we have removed that application from your ios device.
Please check following e.g Objective- C
if([SSKeychain passwordForService:#"your application bundle identifier" account:#"user"] == nil)
{
NSString *UUID = AppDelegate.GetUUID;
[SSKeychain setPassword:UUID forService:#"your application bundle identifier" account:#"user"];
NSString *retrieveuuid = [SSKeychain passwordForService:#"your application bundle identifier" account:#"user"];
NSLog(#"retrieveuuid %#",retrieveuuid);
}
+ (NSString *)GetUUID {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return (__bridge NSString *)string;
}

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.

Unique Identification of iOS device for iOS 7.0 and above

Looking for your help
I am facing a problem while getting Device Identifier. Actually I am using a UIDevice+IdentifierAddition.h, NSString+MD5Addition.h classes to get Identifier, but its return same identifier for all my devices i.e. iPhone 4s (iOS 7.1) & iPhone 5 (iOS 7.1.1).
Can any one have any solution for this problem. because I want a something unique for device specific. its my app requirement.
Important: I want to submit this app on app store, So please, answer must be as per the guidelines
Since iOS 7 it is no longer possible to get any unique device identifiers.
Your options are:
create your own unique ID and save it in the keychain.
use the vendor ID, which will be reset if all the app by the same vendor are removed from the device.
Now it's possible in iOS 11.0+, Apple has introduced a new API called DeviceCheck API with which developers can uniquely identify a device.
As mentioned in the documentation:
Using the DeviceCheck APIs, in combination with server-to-server APIs,
you can set and query two bits of data per device, while maintaining
user privacy. You might use this data to identify devices that have
already taken advantage of a promotional offer that you provide, or to
flag a device that you have determined to be fraudulent. The
DeviceCheck APIs also let you verify that the token you receive comes
from an authentic Apple device that includes your app.
Also, check out the following WWDC17 video starting at 24 min:
https://developer.apple.com/videos/play/wwdc2017/702/
EDIT:
A thoroughly detailed tutorial on this Device Check topic can be found here.
In Objective c
NSString *uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
In Swift
var uniqueId=UIDevice.currentDevice().identifierForVendor.UUIDString as String
println("Your device identifires =>\(uniqueId)")
Unfortunately identifierForVendor changes when you uninstall your application so to guarantee that the it will not change save it in the keychain
I used pod 'SSKeychain' Homepage: https://github.com/soffes/sskeychain
Here is the code
+ (NSString *)getDeviceId {
NSString *appName=[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
NSString *strApplicationUUID = [SSKeychain passwordForService:appName account:#"MY_KEY"];
if (strApplicationUUID == nil) {
strApplicationUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[SSKeychain setPassword:strApplicationUUID forService:appName account:#"MY_KEY"];
}
return strApplicationUUID;
}
[UIDevice uniqueIdentifier]; is deprecated in ios 5 and above.
You can get identifier for vendor using this
NSString *udid = [[UIDevice currentDevice] uniqueIdentifier];
and store this in keychain and use later on.
Also you can check for
1) NSUUID
2)CFUUID
you will get detail description here Unique device identification in ios
If you're trying to identify a device only once i.e., to estimating the number of unique users then I suggest using "advertisingIdentifier" of ASIdentifierManager.
Apple Doc

UDID Replacement in IOS7

Is there is a alternative for UDID. My app will not be going to App Store as i'm using enterprise distribution. So is there any replacement. I tied advertising identifier, open udid, UIID and secure UDID. But if the phone is reset then i will get a new UDID. Any help would be appreciated.
For above 6.0 iOS you can use identifierForVendor Or CFUUIDRef.
-(NSString*)uniqID
{
NSString* uniqueIdentifier = nil;
if( [UIDevice instancesRespondToSelector:#selector(identifierForVendor)] ) {
// iOS 6+
uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else {
// before iOS 6, so just generate an identifier and store it
uniqueIdentifier = [[NSUserDefaults standardUserDefaults] objectForKey:#"identifierForVendor"];
if( !uniqueIdentifier ) {
CFUUIDRef uuid = CFUUIDCreate(NULL);
uniqueIdentifier = ( NSString*)CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
[[NSUserDefaults standardUserDefaults] setObject:uniqueIdentifier forKey:#"identifierForVendor"];
}
}
return uniqueIdentifier;
}//
UPDATE
As Leon Lucardie comment he is right
identifierForVendor will change after app uninstall/reinstall. See here 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.
You have to create vendor id then save it using keychain and get it back once you reset your phone using date time
check this link UUID and UDID for iOS7
After trying all possible replacements. Advertising identifier is the best way to go. It remains same even after phone reset when i tested. If the user turn it off in the settings then we get a null value. Except for this hitch, this is the best replacement so far. Will update if i find any other better replacements.
Easy, Just use this code:
-(NSString *)getUID{
if ([[UIDevice currentDevice] respondsToSelector:#selector(identifierForVendor)]) {
// This is will run if it is iOS6 and above
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else {
// This is will run before iOS6 and you can use openUDID or other
// method to generate an identifier
return [OpenUDID value];
}
}
As you can understand, if you plan to support iOS 5 then you should use OpenUDID (Apple restrict reading the UDID even on iOS 5). With some answers here you would simply get rejected by Apple (my code has been approved in several apps of mine).
Pay attention that identifierForVendor would change if your user would remove the app (or all vendor apps if there are several) and reinstall.
I use the combination APNS token and vendorId. Both are checked to verify cellphone identity and I update them accordingly in cellphone and server when one of those change.
It´s still possible that both change, when the app is uninstalled and/or reset and stored for a few months, then both values would change.
This will cause that next time the cellphone gets the app installed, it will be identified as a new one.
Additional to this I run a process in server that marks as deleted any device which hadn't connected to the server for two months.
In that case user authentication is required and cellphone is added again to the customer's pool of devices.
I have only one app yet, but once I have the second one I might include advertisingId.
These blog posts by Ole should be helpful:
iOS 5: http://oleb.net/blog/2011/09/how-to-replace-the-udid/
iOS 6+: http://oleb.net/blog/2012/09/udid-apis-in-ios-6/
You can use after ios 6+ with Swift 2.2 version.
var uniqueIdentifier: NSString!
uniqueIdentifier = UIDevice.currentDevice().identifierForVendor?.UUIDString

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.

Resources