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
Related
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.
For an in-house application, we were using the following code UIDevice+serialNumber to get the device serial number.
However, it seems that with iOS 8, the registry key "IOPlatformSerialNumber" is empty.
Can the serial number be obtained any other way?
Answer: No.
There are currently floating solutions around abusing the .mobileconfig, but they add other problems due their nature.
UUID was removed for a reason. See the news around privacy and the summon of Apple by the US Senat from 2011 to gain an understanding why this had to be changed.
http://arstechnica.com/apple/2011/04/apple-google-asked-to-join-judiciary-hearing-on-mobile-device-privacy/
Abusing the underlying march port to get the device serial number as replacement of the UUID is not the solution. Same now for abusing the mobile config and guess how long that will work.
You have plenty of decent ways to handle any situation where you used device identification before. Especial in an enterprise environment where you have cryptography and MDM is absolutely no point to track a device like this.
Retrieving the device serial number directly is no longer possible in iOS.
However, if it's simply for an internal enterprise app, something the company I work for is going to implement is this:
During device configuration, copy the serial number and set the device name as the serial number.
Then use Apple's UIDevice API to retrieve the device name.
As Helger stated above, UDID is no longer available in iOS 6+ due to security / privacy reasons. Instead, use identifierForVendor or advertisingIdentifier
Please check UDID Replacement APIs
For iOS 8+
+ (NSString *)deviceUUID
{
if([[NSUserDefaults standardUserDefaults] objectForKey:[[NSBundle mainBundle] bundleIdentifier]])
return [[NSUserDefaults standardUserDefaults] objectForKey:[[NSBundle mainBundle] bundleIdentifier]];
#autoreleasepool {
CFUUIDRef uuidReference = CFUUIDCreate(nil);
CFStringRef stringReference = CFUUIDCreateString(nil, uuidReference);
NSString *uuidString = (__bridge NSString *)(stringReference);
[[NSUserDefaults standardUserDefaults] setObject:uuidString forKey:[[NSBundle mainBundle] bundleIdentifier]];
[[NSUserDefaults standardUserDefaults] synchronize];
CFRelease(uuidReference);
CFRelease(stringReference);
return uuidString;
}
}
You can use identifierForVendor after that store them to keychain and use later. Because value of keychain will not changed when re-install app.
I used to use Open UDID for this purpose. Don't know if it still works.
The serial number for Apple devices can be found under Settings -> General -> About -> Serial number.
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..
I am using UUID of current device. I have to send that ID to a server for registering my device.
So I used a bit of code like:
NSString *uuidString = nil;
CFUUIDRef uuid = CFUUIDCreate(NULL);
if (uuid) {
uuidString = (NSString *)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));
CFRelease(uuid);
}
And I am sending that uuidString to the server.
My concern is that Apple will reject my app for using this UUID and sending to a server?
Please give me idea about this, it's Very important for me now.
Why do you think Apple will reject this?
Apple is just not allowing you to identify device any more, by using the UDID or the MAC address of the device.
If you generate a unique number, which you do, then there should be no problem. Just be aware that the UUID you create with the code you posted will be different every time you call the code.
Thus if you use it to track a user then you should generate it once and save the generated UUID somewhere.
Not an anser to the original question I know, but just to point out that there'a NSUUID now so you can avoid all that CF boilerplate.
NSString *uuidString = [[NSUUID UUID] UUIDString];
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]