This question already has answers here:
UIDevice uniqueIdentifier deprecated - What to do now?
(32 answers)
Closed 9 years ago.
Please, do not mark this as a duplicate. This question is about Simperium and the way it deals with uniqueIdentifier and identifierForVendor.
Simperium is still using
[[UIDevice currentDevice] uniqueIdentifier]
in Simperium.m. This has been deprecated and Apple is now completely rejecting apps that use that call.
I am experimenting with
[[[UIDevice] currentDevice] identifierForVendor] UUIDString];
but I am not sure if there would be any problem doing so.
What do you say?
Best,
According to Apple documents identifierForVendor can be used from iOS 6.0 and later so no issues in using identifierForVendor
It is should work. Because they say
"While you may have removed access and usage of UDIDs from your app,
the invalid binary message indicates that your app uses or accesses
UDIDs. Please check your source code for any occurrence of the
"uniqueIdentifier" method; this is the method that returns a device's
UDID."
So it is only matter of using "uniqueIdentifier" method.
Thanks
You can also use this method for fetching uniqueidentifier for your app.
- (NSString *)createUUID{
NSString *uIdentifier = [[NSUserDefaults standardUserDefaults] objectForKey:#"Unique identifier for test"];
if (!uIdentifier) {
CFUUIDRef uuidRef = CFUUIDCreate(NULL);
CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);
CFRelease(uuidRef);
uIdentifier = [NSString stringWithString:(NSString *)CFBridgingRelease(uuidStringRef)];
[[NSUserDefaults standardUserDefaults] setObject:uIdentifier forKey:#"Unique identifier for test"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
return uIdentifier;
}
Related
This question already has answers here:
iOS unique user identifier [duplicate]
(7 answers)
Closed 5 years ago.
Is there a way to identify a device even after having uninstalled an app and reinstalling again? I found topics where it's possible to get a UUID but it seems that after uninstalling the app the value of the UUID changes
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.
I installed an App called Jodel, you don't have to create an Account to use the app and After uninstalling it, delete iCloud data, logging out from iCloud... an reinstalling it I was still logged in in the App. I assume they use a unique device identifier? Do you have an idea how such mechanism could be implemented?
You can use Keychain Service to store data still after uninstalling app from device.
for more reference about keychain service check this
https://developer.apple.com/documentation/security/keychain_services
Yes, It's Possible
#import "UICKeyChainStore.h"
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self getDeviceIdFromKeychain];
}
- (void)getDeviceIdFromKeychain
{
NSString *deviceID = [UICKeyChainStore stringForKey:#"KEY TO SAVE TO Keychain" service:nil];
// if vandorid from keychain is not nil
if (deviceID)
{
[[NSUserDefaults standardUserDefaults] setObject:deviceID forKey:#"deviceID"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
// else it goes for new vendorid and then stored it to keychan
else if (deviceID == (id)[NSNull null] || deviceID.length == 0 )
{
deviceID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[UICKeyChainStore setString:deviceID forKey:#"KEY TO SAVE TO Keychain" service:nil];
[[NSUserDefaults standardUserDefaults] setObject:deviceID forKey:#"deviceID"];
[[NSUserDefaults standardUserDefaults] synchronize];
// NSLog(#"VendorID Local - %#",deviceID);
}
}
ViewContoller.m
- (void)viewDidLoad
{
NSString *strDeviceId = [[NSUserDefaults standardUserDefaults]objectForKey:#"deviceID"];
}
I wanted to know that How to generate Unique ID of device for iPhone/iPad using Objective-c
so that once application is installed on device , so we should track that deviceID
I have searched to retrieve IMEI of iPhone/iPad , but it is not allowed in objective-c.
Then I searched to generate UDID of iPhone/iPad but it is generating for different ID each time I launched it on simulator .
Yes, UDID is deprecated; we are not allowed to get UDID due to user privacy purposes. Apple does not allow to get any identifiers that uniquely identifies a device, such as IMEI, MAC address, UDID etc.
UUID is the best way to go as of now. But that would be unique for each vendor. You are not assured that it will be unique each time you get the UUID string. Best bet is to store the UUID string to phone's Keychain and retrieve it when needed, with a catch. When you factory-reset your phone, the keychain items would be erased. This limitation should be kept in mind.
UPDATE - IN IOS 10.3 BETA'S:
It seems that Apple has made some changes to how Keychain works in iOS 10.3+. Keychain items stored in the Keychain will be deleted when the all the apps from the specific vendor are uninstalled. According to Apple, the residence of sensitive information of an app even after the app is gone from the device may lead to security risks, so they decided to forbid this kind of behavior.
Developers relying on Keychain storage even after an uninstall for their apps can make use of this WORKAROUND to continue with the intended functionality. According to this workaround, any app can access the information stored in that specific Keychain Access Group, so it is recommended that adding an extra layer of encryption to your data will protect it with even more security, although keychain encrypts items by default.
UPDATE - IOS 10.3.3 (STABLE):
It seems that the keychain items deletion was a BUG in early betas of iOS 10.3.3 and was fixed later in the stable release. This might have been caused during betas since strange things can happen during that phase. It should be no problem to use Keychain hereafter.
You can use UUID (Universal User Identification). Following link contains apple documentation
https://developer.apple.com/reference/uikit/uidevice/1620059-identifierforvendor
https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS7.html#//apple_ref/doc/uid/TP40013162-SW1
you can use this code for UUID:
//Objective-C
NSString * string = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
//Swift
let deviceID = UIDevice.currentDevice().identifierForVendor?.UUIDString
//Swift 3
let deviceID = UIDevice.current.identifierForVendor?.uuidString
Use the below code to get UDID for iOS device
Use KeychainItemWrapper Class download from URL
KeychainItemWrap
NSString *uuid;
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:#"AC_APP_UUID" accessGroup:nil];
NSString *keychainUUID = [keychain objectForKey:(__bridge id)(kSecAttrAccount)];
NSString *appVersion = [NSString stringWithFormat:#"%#",#"1.0"];
[keychain setObject:appVersion forKey:(__bridge id)(kSecAttrDescription)];
if (keychainUUID==nil||[keychainUUID isKindOfClass:[NSNull class]]||keychainUUID.length==0) {
uuid = [[NSUUID UUID] UUIDString];
[keychain setObject:uuid forKey:(__bridge id)(kSecAttrAccount)];
}else{
uuid = [keychain objectForKey:(__bridge id)(kSecAttrAccount)];
}
Anyone coming here post 2017, Apple has implemented DeviceCheck for this purposes.
https://developer.apple.com/documentation/devicecheck#overview
You can use DeviceCheck to see if this particular device has installed or used your particular app. It doesn't give you a unique id to the phone, but it does allow you to see if a user has burned through a promotion or not.
You cannot take IMEI and phone number of user mobile, Apple is restricted to get these uniqueID's.
You have to store UDID in keychain. for this you have to download keychainwrapper class and store the UDID generated by above code:
UIDevice *device = [[UIDevice alloc]init];
NSString *idForVend = [NSString stringWithFormat:#"%#", [device identifierForVendor]];
NSLog(#"Identifier For Vendor : %#",idForVend);
follow this link it will solve your problem for sure: https://stackoverflow.com/questions/16459879/how-to-store-a-string-in-keychain-ios , iOS?
If you use this If you delete app And install again it will remain same DeviceID.
#import <AdSupport/AdSupport.h>
NSString* sClientID = [[[ASIdentifierManager sharedManager]advertisingIdentifier] UUIDString];
The Best UUID because:
it will never change (*even if the app will be deleted)
Apple approve it.
Solution is :
You can do it with DeviceToken . DeviceToken are uniq for all mobile.
Code is here :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[UIApplication sharedApplication] respondsToSelector:#selector(registerUserNotificationSettings:)])
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}
return yes;
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString *AppDeviceToken=[[NSString alloc] initWithFormat:#"%#",deviceToken];
//NSLog(#"My token is: %#", self.AppDeviceToken);
AppDeviceToken = [self.AppDeviceToken stringByReplacingOccurrencesOfString:#" " withString:#""];
AppDeviceToken = [self.AppDeviceToken stringByReplacingOccurrencesOfString:#"<" withString:#""];
AppDeviceToken = [self.AppDeviceToken stringByReplacingOccurrencesOfString:#">" withString:#""];
NSLog(#"%#'s Device Token is : %#",[[UIDevice currentDevice] name],AppDeviceToken);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
}
Device token are uniq for all device.
According to apple docs, sometimes it happens that the method [ASIdentifierManager sharedManager].advertisingIdentifier can return a nil value and I really need this value in my app:
https://developer.apple.com/library/prerelease/ios/documentation/AdSupport/Reference/ASIdentifierManager_Ref/index.html#//apple_ref/occ/instp/ASIdentifierManager/advertisingIdentifier
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.
How long should I wait? What approach should I use in this case? Maybe keep trying to get the advertisingIdentifier until it is available? Or should I tell the user to try to restart the app? Any ideas?
Thanks.
You should manually create UUID and should save it in preferences.
NSString *UUID = [[NSUserDefaults standardUserDefaults] objectForKey:kApplicationUUIDKey];
if (!UUID) {
CFUUIDRef uuid = CFUUIDCreate(NULL);
UUID = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
[[NSUserDefaults standardUserDefaults] setObject:UUID forKey:kApplicationUUIDKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
You can effectively get a notification when the user unlocks the phone using protected files and listening for applicationProtectedDataDidBecomeAvailable
Say I have an app - 'MyApp' - is there a way to consistently get a device identifier string within 'MyApp'?
i.e. Any time a user uses 'MyApp' on a particular device, I could call the API and get back the same string all the time?
identifierForVendor will change between installs, best to use CFUUIDCreate.
if ([[NSUserDefaults standardUserDefaults] valueForKey:#"UUID"] == nil) {
CFUUIDRef uuid = CFUUIDCreate(NULL);
NSString *uniqueIdentifier = ( NSString*)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));
CFRelease(uuid);
[[NSUserDefaults standardUserDefaults] setObject:uniqueIdentifier forKey:#"UUID"];
}
The above will survive app re-installs.
Apple may reject your app for sending personally identifiable information. Use an advertising ID instead:
#import <AdSupport/AdSupport.h>
// Advertising ID
ASIdentifierManager *adManager = [ASIdentifierManager sharedManager];
NSUUID *uuid = [adManager advertisingIdentifier];
NSString *stringRepresentation = uuid.UUIDString;
Just make sure you abide by Apple's guidelines for UDID usage, including restrictions for users that have checked 'Restrict Ad Tracking' in Settings.
Apple doesn't allowed to add application to the app store that used the [UIDevice uniqueIdentifier] because the property become private in iOS SDK 6.0
What are the Alternatives?
you can use/create "your own" UDID:
+(NSString *)getUUID
{
CFUUIDRef newUniqueId = CFUUIDCreate(kCFAllocatorDefault);
NSString * uuidString = (__bridge_transfer NSString*)CFUUIDCreateString(kCFAllocatorDefault, newUniqueId);
CFRelease(newUniqueId);
return uuidString;
}
You should keep in mind that this method will produce a different id on every call so you should persist it some how, thus it is not an identical alternative to the UDID, but for most uses it is even better like that.
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
- (NSString*)deviceId {
NSString *udidString;
if (SYSTEM_VERSION_LESS_THAN(#"6.0")) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
udidString = [defaults objectForKey:#"udidKey"];
if (!udidString) {
CFUUIDRef identifierObject = CFUUIDCreate(kCFAllocatorDefault);
// Convert the CFUUID to a string
udidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, identifierObject);
[defaults setObject:udidString forKey:#"udidKey"];
[defaults synchronize];
CFRelease((CFTypeRef) identifierObject);
}
} else {
udidString = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
}
return udidString;
}
if gets warning on the line: udidString = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; it means the Xcode SDK is less than 6.0
(Xcode 4.3 contains iOS SDK 5.1, Xcode 4.5 contains iOS SDK 6.0)
to update Xcode iOS SDK:
simply download the newest Xcode available on App Store (Apple doesn't give an option to download only the SDK).
if want to keep current Xcode version just:
download the newest Xcode version.
copy iOS SDK Library from :
newestXcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/
to
oldXcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/
Reopen old Xcode and thats it!