How to preserve identifierForVendor in ios after uninstalling ios app on device?
Solution 1
You may keep it in KeyChain
-(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;
}
Solution 2
Generally, don't use identifierForVendor
. Instead, use NSUUID
to generate a custom UUID and store that in the keychain (because the keychain isn't deleted if the app is deleted and reinstalled).
Solution 3
Addition to @nerowolfe's answer.
SSKeychain uses kSecAttrSynchronizableAny
as a default synchronization mode. You probably don't want identifierForVendor
to be synced across multiple devices so here is a code:
// save identifierForVendor in keychain without sync
NSError *error = nil;
SSKeychainQuery *query = [[SSKeychainQuery alloc] init];
query.service = @"your_service";
query.account = @"your_account";
query.password = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
query.synchronizationMode = SSKeychainQuerySynchronizationModeNo;
[query save:&error];
Solution 4
You can try use KeyChain to save your VendorIdentifier, that will exist till your device is reset, even if you uninstall your app.
Solution 5
Swift version
func UUID() -> String {
let bundleName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
let accountName = "incoding"
var applicationUUID = SAMKeychain.passwordForService(bundleName, account: accountName)
if applicationUUID == nil {
applicationUUID = UIDevice.currentDevice().identifierForVendor!.UUIDString
// Save applicationUUID in keychain without synchronization
let query = SAMKeychainQuery()
query.service = bundleName
query.account = accountName
query.password = applicationUUID
query.synchronizationMode = SAMKeychainQuerySynchronizationMode.No
do {
try query.save()
} catch let error as NSError {
print("SAMKeychainQuery Exception: \(error)")
}
}
return applicationUUID
}
Harshavardhan
Updated on July 11, 2022Comments
-
Harshavardhan almost 2 years
I am developing an iOS app which calls web-service for login and at that time i send login credentials to web server along with vendor identifier (identifierForVendor),to identify device uniquely for those credentials.So user can have only one device and one credential.
I got identifierForVendor with
NSString *uuid = [[UIDevice currentDevice] identifierForVendor].UUIDString
This identifier will then store in database of web server and also in device database.Next time when user opens application and will try to download data from web server firstly local identifierForVendor on users device will compare with identifier stored on web server.
Problem occurs when user uninstall app and reinstall it, I found that identifierForVendor is changed. So user cannot proceed further.
I read apple documentation UIDevice Documentation
As mention there, if all app from same vendor uninstalls from device then at time of new installation of any app from that vendor will take new identifierForVendor.
So how to deal with this in my case ?
-
Kristof Van Landschoot almost 10 yearsWill this work if iCloud KeyChain synchronisation is enabled?
-
nerowolfe almost 10 yearsInteresting question. Don't know
-
PrasadW over 9 yearsIs there a possibility for the identifierForVendor to return a duplicate in case for different versions of the same app on different devices?
-
Wain over 9 yearsI would expect yes, but an infinitesimally small chance
-
Marcus Adams about 9 yearsNo chance of duplication. UUIDs are not random. They are calculated, and part of the UUID is the device ID.
-
rckoenes about 9 years@DouglasHeld I understand that, but Apple made that impossible and I tried to explain why you should not.
-
rckoenes about 9 yearsThis will not work when the KeyChain is synced, all synced device will get the same verdor id.
-
Ash about 9 years@rckoenes You need to identify a device if you require hardware binding. How else would you stop a user from installing it on multiple devices? One guy pays once and then all his friends get it for free as well using his login credentials!? Doesn't seem reasonable to the developers.
-
rckoenes about 9 years@ash I hear you, but Apple is not allowing this. Per Apple Account 5 devices are supported. Restricting this is against Apple policy.
-
Jonny almost 9 yearsI'm just gonna vote this down because of the sync issue mentioned above.
-
jayatubi over 8 yearsHow about UIPasteBoard?
-
loretoparisi over 8 years@KristofVanLandschoot to make it works with iCloud you need to use a keychain within iCloud: stackoverflow.com/questions/11489864/icloud-sync-keychain
-
loretoparisi over 8 years+1 This is a very simple solution, that combined with iCloud keychain sync (using the attribute kSecAttrSynchronizable), make the best solution at this question.
-
jcesarmobile over 8 years@loretoparisi if you use kSecAttrSynchronizable wouldn't you have the same value on all your devices?
-
loretoparisi over 8 years@jcesarmobile exactly, if you add
kSecAttrSynchronizable
to @gautam-jain code, you will get it on iCloud app properties and the synchronized to all your devices. -
jcesarmobile over 8 yearsthen it's not a good idea if you want each device to have a different value
-
loretoparisi over 8 years@jcesarmobile yes depending of your needs, you can preserve the device's identifier, the device's vendor of both like properties
identifierForVendor
andadvertisingIdentifier
fromASIdentifierManager
. -
mcfedr over 8 years"UUIDs created by NSUUID conform to RFC 4122 version 4 and are created with random bytes." - But none the less the chances of a repeat are very small, as someone else posted "Only after generating 1 billion UUIDs every second for the next 100 years, the probability of creating just one duplicate would be about 50%." - stackoverflow.com/a/1155027/859027
-
blkbam over 7 yearsI wouldn't call this a Swift version as it requires a 3rd party object
-
crawler over 7 yearsFrom Cocoapods: SSKeychain has been deprecated in favor of SAMKeychain
-
griga13 over 7 yearsYou can check my answer regarding SSKeychain and synchronization mode
-
Muhammad Umair almost 7 yearsiOS11+ new API called
DeviceCheck
can uniquely identify a device, check answer: stackoverflow.com/questions/24753537/… -
Asif Raza over 6 yearsUse updated version github.com/soffes/SAMKeychain of SSKeyChain.
-
Andreas Paulsson over 6 yearsWatch out for keychain though, items in the keychain currently survive an app uninstall-install cycle, but that may change in the future. In iOS 10.3 beta 3, keychain items was removed but that changed back in the final version. See more at stackoverflow.com/questions/18911434/… .
-
Alessio Dal Bianco over 6 years@NSIceCode it seems that the token returned by DeviceCheck API is ephemeral (is not stable) see the docs: developer.apple.com/documentation/devicecheck/dcdevice/…
-
S P Balu Kommuri over 6 yearsI'm using getting the identifier for vender as nil sometimes only in iPhone 8 and iPhone X, can anyone suggest why I'm getting the nil instead of UDID? @NSIceCode
-
ForceMagic over 6 yearsUnfortunately, they changed it recently, the KeyChain is not safe to store persistent data anymore. stackoverflow.com/a/48405739/62921
-
ForceMagic over 6 yearsIt is good to use the identifierForVendor, but this should not be store in the keychain anymore. stackoverflow.com/a/48405739/62921 It's not persistent since iOS 10.3
-
ForceMagic over 6 yearsKeychain and UIPasteBoard are not persistent anymore : stackoverflow.com/a/48405739/62921
-
iphonic over 6 years@ForceMagic Thanks for update, my answer is 3 years old, will find another way, al the answers to the question still stores in Keychain they are not updated, its pointless to downvote, as it used to work when the question was asked..
-
ForceMagic over 6 yearsYeah I do understand pretty much all the answers are old. I was seeing the downvote more like a "this is not true anymore" as opposed to "this is a bad answer". But maybe I'm wrong.
-
iphonic over 6 years@ForceMagic The answer still stands true see this stackoverflow.com/a/18944600/790842 and this stackoverflow.com/a/43063683/790842
-
ForceMagic over 6 yearsFrom your link :
At Apple Documentation It is suggested that this is about to change and we should NOT rely on keychain access data being intact after an app uninstallation
-
iphonic over 6 years@ForceMagic This means my answer still works, for SHOULD NOT rely, YES of course I personally never use Keychain, but as far as it is working and useful for solving some problem we can use it, even if it is not the best solution, I deserve upvote as the answer is still working. Thanks.
-
Ammar Mujeeb over 5 yearsswift 4 compile time error: Use of unresolved identifier 'SSKeychain'; did you mean 'SecKeychain'?
-
nerowolfe over 5 yearsSSKeychain has been deprecated in favor of SAMKeychain (it is any third party library)
-
Matt Mc over 4 years@ForceMagic you were correct, but now you're incorrect :)
-
ForceMagic over 4 years@MattMc Haha! so they made it persistent once more? XD