Unique Identifier should not change with iOS version change - ios

I'm developing an application which is using device unique identifier to register device with server.
I am using MacAddress to get unique identifier of device, but in iOS7 it will return same(static for all device).
I found other alternate as
NSUUID *vendorId = [[UIDevice currentDevice] identifierForVendor];
But that will change as iOS device changed.
So can anyone suggest me some unique identifier which will not change if iOS version change it should be same for all iOS version (iOS7, iOS6).

There is a simple answer: It is not possible. Here you have an overview over the identifiers: The Developer’s Guide to Unique Identifiers

Apple is not allowing to use the Device's UDID to identify the users. So you can do it in other way.
Instead of sending the UDID to the server, create a unique Id on the server and put that ID in the application to recognize the user. In this way, you will not break the Apple's guidelines and the problem of varying the iOS versions also get resolved with this.

Just store the UUID into the keychain.
sskeychain refers to https://github.com/samsoffes/sskeychain
code as following^^
NSString *identifier = [SSKeychain passwordForService:kSSToolkitTestsServiceName account:kSSToolkitTestsAccountName];
if (identifier != nil && [identifier length] > 0) {
return identifier;
}
identifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[SSKeychain setPassword:identifier forService:kSSToolkitTestsServiceName account:kSSToolkitTestsAccountName];
return identifier;

Unfortunately Apple disallows application to Uniquely identify a device (AS per them it violates User Privacy).. So you have either left with vendor ID or Advertisement ID.. another thing which you can try is that writing a web service which provides a unique ID to your app on first login and you will store that in in key chain or DB on your device..

Related

Obtaining a Unique Device ID [duplicate]

I have used mac address to identify iOS devices in server side. When run my application with iOS 7 unable to retrieve the correct mac address. Alternately i used
NSUUID *oNSUUID = [[UIDevice currentDevice] identifierForVendor];
[strApplicationUUID setString:[oNSUUID UUIDString]];
property. But this value also changed after every new installation of application. Now i want detect particular device in server side? How can i get some unique id per device in iOS?
You can no longer get a unique ID per device. identifierForVendor is the best you're going to get. Apple has systematically disabled identifying a specific device so that users' IDs can't be passed around by marketers.
To get the identifier ID as a string, you can use
let deviceId = UIDevice.current.identifierForVendor?.uuidString
UPDATE
If you want a universal ID then you have the option to use advertisingIdentifier. However, if the user has limited ad tracking in their device settings then this value will simply return all zeroes.
import AdSupport
let identifierManager = ASIdentifierManager.shared()
if identifierManager.isAdvertisingTrackingEnabled {
let deviceId = identifierManager.advertisingIdentifier.uuidString
}
N.B. Apple recommends that this code only be used by companies building advertisement frameworks, rather than the app developers themselves. If you use this within your code for non-ad-related purposes then prepare to have your app rejected.
The best way to get the device id is identifierForVendor
UIDevice *device = [UIDevice currentDevice];
NSString *currentDeviceId = [[device identifierForVendor]UUIDString];
UPDATE
For Swift 4.1 use
UIDevice.current.identifierForVendor?.uuidString
Getting device ID in
Swift 3
let device_id = UIDevice.currentDevice().identifierForVendor?.UUIDString
Swift 4:
let device_id = UIDevice.current.identifierForVendor!.uuidString
Getting Device Id in Swift 3.x
let deviceId = UIDevice.current.identifierForVendor?.uuidString
You can use this lib: https://github.com/fabiocaccamo/FCUUID
Please look on the table in the Persistence section. uuidForDevice will cover the most of needed cases and it is the best replacement to udid from old versions of iOS.
Examples in Readme are in Objective-C but it works with Swift too. I have used it since Swift first release until now (Swift 4.1).
For Swift 5
let deviceId = UIDevice.current.identifierForVendor?.uuidString
You'll have to use UIDevice's identifierForVendor method like so:
let deviceId = UIDevice.current.identifierForVendor?.uuidString
But as explained here in great detail: https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor
the ID changes on every reinstall of the app (from AppStore).
One easy solution to circumvent this is to use the Keychain to store the deviceId once acquired. If the keychain item is not present - which will be the case for the first install* - acquire the deviceId as stated above and store it in the keychain.
*) This is iOS so there has to be some gotchas: If the device is reset or restored from backup, keychain items might disappear. So there's no 100% chance here, but since this scenario is quite unlikely, it's the best choice you've got.

Uniquely identify the device in iOS

I am developing a corporate application on the iPad for a certain business requirement.
This app is meant to use in a specific number of devices which is predefined by the admin.
But I also need the application to reject any login requests even if it is from an authorised user,when he or she is using a device which is not defined by the admin.
Edits:
Say I have 2 devices and I have my credentials to login to the app, And my need is, to restrict the login from the devices which is not mine.
For that I have to identify whether the login request is comes from my device or not.
Previously we could use device UDID to do this, but now it is deprecated.
Can any one please suggest a method to implement this ?
try this. for more info check UIDevice
// IOS 6+
NSString *uniqueIdentifier = [[NSString alloc] initWithString:[[[UIDevice currentDevice] identifierForVendor] UUIDString]];
You can use iCloud over here because UUID has been deprecated and vendorId is uniqe but might be change if you uninstall the app and install it agian,
So I would suggest iCloud will be safer, what you cna do is at the time of application launch you can generate one token which is unique and save it to your iCloud data storage along with user credentials,
So from the next time onwards when user will try to login you can check it with iCloud.
How about using Apple's enterprise distribution system? That will allow you to deploy the app to a corporation, and have tight access control.
https://developer.apple.com/programs/ios/enterprise/
Just Trick:
You can Implement APNS code to your Project and Get Device Token.
The Device Token is Unique One. But The user Must Allow the APNS.
Note: APNS Device Token is changed to Following reasons.
Change of Bundle id.
Change of Development Mode(Sandbox/Production)
I have implemented a solution for exactly your problem, The best solution (and Apples recommended route) is to create a UUID unique to your App like this:
NSString *uuidString = nil;
CFUUIDRef uuid = CFUUIDCreate(NULL);
if (uuid) {
uuidString = (NSString *)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));
CFRelease(uuid);
}
Then, and this is the key, you can store that to the iOS keychain (Handy classes here: https://github.com/lukef/IXKeychain) and values in the iOS keychain are NOT removed when the user uninstalls the App, so you can persist your own UUID through App installs which is a key part of managing a specific number of devices against a user account.
This method will return a string for every device. Since it is gonna change every time for single device
so we are storing it in a keychain and can refer it whenever we need it.
+ (NSString *) uniqueDeviceIdentifier
{
NSString *deviceUUID = [[SGKeyChain defaultKeyChain] stringForKey:#"uniqueId"];
if (!deviceUUID) {
if (!deviceUUID.length) {
NSString *deviceUUID = #"";
CFUUIDRef uuidRef = CFUUIDCreate(NULL);
CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);
CFRelease(uuidRef);
deviceUUID = [NSString stringWithFormat:#"%#",[NSString stringWithString:(__bridge_transfer NSString *)uuidStringRef]];
[[SGKeyChain defaultKeyChain] setObject:deviceUUID forKey:#"uniqueId" accessibleAttribute:kSecAttrAccessibleAlways];
}
}
return deviceUUID;
}
yo can refer to this repository... https://github.com/sgup77/SGKeyChainWrapper for SGKeyChain implementation
Ok I will share the approach that we follow for a B2B enterprise app.
.
Every User has login Id and Password.
1. So user register his device with Server using deviceReg API which takes clientDeviceId as param(client generated uuid) along with username and pass.
2. Server returns a server generated unique identifier to be used by application on that particular device.
Conclude - in this way you can restrict the user with a certain device.
You can use below method to generate deviceSpecific client UUID
- (NSString *)getUuid
{
CFUUIDRef uuidRef = CFUUIDCreate(NULL);
CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);
CFRelease(uuidRef);
NSString *uuid = [NSString stringWithString:(__bridge NSString *)uuidStringRef];
CFRelease(uuidStringRef);
return uuid;
}
Please note:
I remove the explanation about using AuthKey, AccessToken and others which we use for security purpose as you do not use any auth server.
I hope it helps.
Update 1.
Since you are having an enterprise application so i am sure you would be having atleast the user e-mail ids.
So the account manager should than 1st send a email with one time token to all active accounts.
This token can be requested by the application while registering the device and send to server for validation.
Also the server invalidates the token once used to avoid misuge.
There should be a migrAtion api which uses the server generated device id and a migration token if user migrates the device.

Unique Identification of iOS device

I was using Mac address for unique identification of the iOS device, but from iOS7 the system always returns 02:00:00:00:00:00 value. I had searched three options for the mentioned issue:
Vendor identification
Advertising identification
Getting serial number using IOUnit framework
Since the IOUnitFramework is not approved by appstore, cant use it in my application. And the vendor identification and advertising identification return very long values.
Is there any other possible way to uniquely identify the ios device?
Thanks in advance
Storing a unique identifier in keychain is another option. But we can't access the keychain directly from our ios device.So is there any other alternative way for unique identification of the device?
No, Apple does not allow you to uniquely identify devices any more. This has to do with the user privacy. Since you are not identifying the user but a device.
Also don't use the ASIdentifierManager for identifying device, Apple is now reject apps that use this to identify device. The ASIdentifierManager is only to be used for advertisement purposes.
The only option left is either the the [[UIDevice currentDevice] identifierForVendor] or save your own custom create ID to the keychain.
Saving to your own create id to the keychain will make sure that if the user deletes the app en reinstalls it later you can still access this value.
You can use UDID of the device by which you can uniquely identify iPhone device
Create UIID from this method
- (NSString *)createUUID
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
[[NSUserDefaults standardUserDefaults] setObject:(__bridge NSString *)string forKey:#"UUID"];
[[NSUSerDefaults standardUserDefaults] synchronize];
return (__bridge NSString *)string;
}
Use this where you need the device UDID
- (NSString*)UUID
{
return [[NSUserDefaults standardUserDefaults] ObjectForKey:#"UUID"];
}
You might check on this link and this link. It shows you multiple ways to identify your iOS device. They are a little outdated, but identifierForVendor and advertisingIdentifier still works.
Advertising identifier is mainly used for advertising purpose, but Apple is encouraging using this identifier for any needs.
advertisingIdentifier is part of the new AdSupport.framework. The ASIdentifierManager singleton exposes the method advertisingIdentifier and calling that returns an instance of the NSUUID class.
NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
Identifier for vendor also return an UUID string :
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
There are a lot of ways for to get an unique identifier. You can get identifierForVendor as some guys recommended you or create an UUID as mokujin recommended you. Even there are external sources libraries like SecureUDID, OpenUDID... but all these has the same problem, if you remove your app and reinstall, you will get different identifier.
I have been working in a big company where they used MDM (Mobile Iron) which give you the posibility of to get the real UDID. I think you are not using MDM in your project so I recommend you to use one of the choice recommended here for me and others users and save it in your keychain. After of this, you should to check if you have this value keep in your keychain, for using it, if not, you should to get it and keep it.
Don´t save it in your NSUserDefaults because if you delete your app, your info kept there will be deleted.
For use your keychain I recommend you to use this class from Apple KeychainItemWrapper
Apple kills the way of tracking application, though we can track application using following ids
Identifier for vendor
NSUUID
CFUUID
But this device ids will reset if you factory reset your phone.
You will get detail description over here unique device identification in iOS

Can device token of Push Notification be used as a unique identifier?

Problem: using UDID is deprecated - we cannot use it anymore.
There are some solutions on the net: generate GUID and store it in the "safe place", iCloud, IdentifierForVendor starting with iOS6, OpenUID, SecuredID and so on...
Request:
I need to have a unique identifier of the Device to store user data on our server.
Question:
Can I use deviceToken of Push Notification as a unique identifier?
What are the pros and cons of this idea?
(-) user can disable push notifications
(+) unique number
(+) supported in all iOS
This is a terrible idea, the token can change if the user changes device or for some other unknown reason.
The user can have multiple devices
If the user reinstalls the app they can get an other token
It's not 100% that the user will keep the same token.
And most important of all: You are identifying devices not users!
One solution is to generate a UUID and save it in the user keychain where you retrieve it. But this can also be removed if the user clear the device.
You best option is to allow the user to login with an account, which that can create. Then you can combine this with the UUID in the keychain.
You should use identifierForVendor. The deviceToken for push notification is unique, but CAN change.
The token can change if the user reset the device, for unique device identifying you can use the following code
float currentVersion = 6.0;
NSString *udid = nil;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= currentVersion)
{
//below code is taken from the Apple Sample code, to check you can download the files
https://developer.apple.com/library/ios/releasenotes/StoreKit/IAP_ReceiptValidation
// OR
http://developer.apple.com/library/ios/releasenotes/StoreKit/IAP_ReceiptValidation/VerificationController.zip (line number 319)
udid = [UIDevice currentDevice].identifierForVendor.UUIDString;
}
else
{
//may cause apple rejection
udid = [UIDevice currentDevice].uniqueIdentifier;
//i think we can use the below link for ios5 or below but not sure it may accept or reject
https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5
}
//just saw a link which may help you better and have a look at image
http://www.doubleencore.com/2013/04/unique-identifiers/
can someone suggest the best way to persist the unique id even after reinstall app, delete app or system restart or system boot or factory reset

CFUUIDCreate UUID changes constantly

I am a beginner iPhone app developer and I am trying to show the iPhone or App unique identifier on a label through an IBAction button. I researched a little and know that some of the code have been deprecated and CFUUID is used instead. The code below is what I used. However, every time I touch the IBAction button, the UUID changes. What am I doing wrong?
CFUUIDRef udid = CFUUIDCreate(NULL);
NSString *udidString = (NSString *) CFUUIDCreateString(NULL, udid);
uuid.text= udidString;
I think you have misunderstood the purpose of CFUUIDCreate(), Read its documentation you'll understand.
I guess the API is serving it's purpose properly, which is to create universally unique identifier means every time you call this it will return you back unique identifier randomly.
You can use
[[UIDevice currentDevice] uniqueIdentifier]
However, this method is depreciated. In order to get a unique identifier for each device, you can still use CFUUIDCreateString and save the output to user defaults. Load this value each time the app runs. If the app is deleted and then reinstalled this value will be different.
If you do need a unique identifier across app installs you can use the network MAC address.
As mentioned above, CFUUIDCreate is intended to create a different UUID each time it is run. You can create one, and store it in your app if you like, or you could try something like https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5 - basically, it provides a uniqueGlobalDeviceIdentifier function on the UIDevice, using an MD5 hash of the MAC address as its basis.
[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]

Resources