How to preserve identifierForVendor in ios after uninstalling ios app on device?

55,364

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
}
Share:
55,364
Harshavardhan
Author by

Harshavardhan

Updated on July 11, 2022

Comments

  • Harshavardhan
    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
    Kristof Van Landschoot almost 10 years
    Will this work if iCloud KeyChain synchronisation is enabled?
  • nerowolfe
    nerowolfe almost 10 years
    Interesting question. Don't know
  • PrasadW
    PrasadW over 9 years
    Is there a possibility for the identifierForVendor to return a duplicate in case for different versions of the same app on different devices?
  • Wain
    Wain over 9 years
    I would expect yes, but an infinitesimally small chance
  • Marcus Adams
    Marcus Adams about 9 years
    No chance of duplication. UUIDs are not random. They are calculated, and part of the UUID is the device ID.
  • rckoenes
    rckoenes about 9 years
    @DouglasHeld I understand that, but Apple made that impossible and I tried to explain why you should not.
  • rckoenes
    rckoenes about 9 years
    This will not work when the KeyChain is synced, all synced device will get the same verdor id.
  • Ash
    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
    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
    Jonny almost 9 years
    I'm just gonna vote this down because of the sync issue mentioned above.
  • jayatubi
    jayatubi over 8 years
    How about UIPasteBoard?
  • loretoparisi
    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
    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
    jcesarmobile over 8 years
    @loretoparisi if you use kSecAttrSynchronizable wouldn't you have the same value on all your devices?
  • loretoparisi
    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
    jcesarmobile over 8 years
    then it's not a good idea if you want each device to have a different value
  • loretoparisi
    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 and advertisingIdentifier from ASIdentifierManager.
  • mcfedr
    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
    blkbam over 7 years
    I wouldn't call this a Swift version as it requires a 3rd party object
  • crawler
    crawler over 7 years
    From Cocoapods: SSKeychain has been deprecated in favor of SAMKeychain
  • griga13
    griga13 over 7 years
    You can check my answer regarding SSKeychain and synchronization mode
  • Muhammad Umair
    Muhammad Umair almost 7 years
    iOS11+ new API called DeviceCheck can uniquely identify a device, check answer: stackoverflow.com/questions/24753537/…
  • Asif Raza
    Asif Raza over 6 years
    Use updated version github.com/soffes/SAMKeychain of SSKeyChain.
  • Andreas Paulsson
    Andreas Paulsson over 6 years
    Watch 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
    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
    S P Balu Kommuri over 6 years
    I'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
    ForceMagic over 6 years
    Unfortunately, they changed it recently, the KeyChain is not safe to store persistent data anymore. stackoverflow.com/a/48405739/62921
  • ForceMagic
    ForceMagic over 6 years
    It 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
    ForceMagic over 6 years
    Keychain and UIPasteBoard are not persistent anymore : stackoverflow.com/a/48405739/62921
  • iphonic
    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
    ForceMagic over 6 years
    Yeah 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
    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
    ForceMagic over 6 years
    From 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
    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
    Ammar Mujeeb over 5 years
    swift 4 compile time error: Use of unresolved identifier 'SSKeychain'; did you mean 'SecKeychain'?
  • nerowolfe
    nerowolfe over 5 years
    SSKeychain has been deprecated in favor of SAMKeychain (it is any third party library)
  • Matt Mc
    Matt Mc over 4 years
    @ForceMagic you were correct, but now you're incorrect :)
  • ForceMagic
    ForceMagic over 4 years
    @MattMc Haha! so they made it persistent once more? XD