¿Cómo conservar el identificador ForVendor en ios después de desinstalar la aplicación ios en el dispositivo?

Estoy desarrollando una aplicación de iOS que llama al service web para iniciar session y en ese momento envío cnetworkingenciales de inicio de session al server web junto con el identificador de proveedor (identifierForVendor), para identificar el dispositivo de forma única para esas cnetworkingenciales. Así, el usuario puede tener solo un dispositivo y una cnetworkingencial .

Obtuve el identificador ForVendor con

NSString *uuid = [[UIDevice currentDevice] identifierForVendor].UUIDString 

Este identificador se almacenará en la database del server web y también en la database del dispositivo. La próxima vez que el usuario abra la aplicación e intente download los datos del server web, primero el identificador local ForVendor en el dispositivo del usuario se comparará con el identificador almacenado en el server web.

Se produce un problema cuando la aplicación de desinstallation del usuario la reinstala, encontré que se cambia el identificador ForVendor. Entonces, el usuario no puede seguir adelante.

Leí documentation de Apple. Documentación de UIDevice.

Como se menciona allí, si toda la aplicación del mismo proveedor se desinstala desde el dispositivo, entonces al momento de la nueva installation de cualquier aplicación de ese proveedor se tomará un nuevo identificador ForVendor.

Entonces, ¿cómo lidiar con esto en mi caso?

Puede savelo en 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; } 

Generalmente, no use el identifierForVendor . En su lugar, use NSUUID para generar un UUID personalizado y almacenar eso en el llavero (porque el llavero no se elimina si la aplicación se elimina y vuelve a instalar).

Además de la respuesta de @ nerowolfe.

SSKeychain usa kSecAttrSynchronizableAny como modo de synchronization pnetworkingeterminado. Probablemente no desee que el identifierForVendor ForVendor se sincronice en varios dispositivos, por lo que aquí hay un código:

 // 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]; 

Puede intentar usar KeyChain para save su VendorIdentifier , que existirá hasta que se restablezca su dispositivo, incluso si desinstala su aplicación.

De acuerdo. No quería usar un tercero, es decir, SSKeychain. Este es el código que probé, bastante simple y funciona bien:

  NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]; KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:bundleId accessGroup:nil]; if(![keychainItem objectForKey:(__bridge id)(kSecValueData)]){ NSString *idfa = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; [keychainItem setObject:idfa forKey:(__bridge id)(kSecValueData)]; NSLog(@"saving item %@", [keychainItem objectForKey:(__bridge id)(kSecValueData)]); }else{ NSLog(@"saved item is %@", [keychainItem objectForKey:(__bridge id)(kSecValueData)]); } 

Versión Swift

 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 } 

No hay una forma definitiva de vincular un número único a un dispositivo, esto no está permitido con las pautas de privacidad de Apple.

Puede intentar save su propia identificación única en el llavero, pero si el usuario borra su dispositivo, esta identificación también desaparecerá.

En general, es incorrecto vincular un dispositivo a un usuario , ya que no se identifican más usuarios, sino dispositivos. Por lo tanto, solo debe cambiar su API para que el usuario pueda volver a iniciar session y que la ID del proveedor esté vinculada a la count de los usuarios.

Además, ¿qué sucede cuando el usuario tiene más de un dispositivo, como un iPhone y iPad, y usa su aplicación en ambos? Como su authentication se basa en una ID única, no se puede hacer.

Utilicé el pod KeychainAccess para este problema.

En su file pod:

 pod 'KeychainAccess', '~> 2.4' //If you are using Swift 2.3 pod 'KeychainAccess' //Defaults to 3.0.1 which is in Swift 3 

Importar el module KeychainAccess en el file donde desea configurar UUID en llavero

 import KeychainAccess 

Use el código siguiente para configurar y get UUID de llavero:

Nota: BundleId es key y UUID es valor

 var bundleID = NSBundle.mainBundle().bundleIdentifier var uuidValue = UIDevice.currentDevice().identifierForVendor!.UUIDString //MARK: - setVenderId and getVenderId func setVenderId() { let keychain = Keychain(service: bundleID!) do { try keychain.set(venderId as String, key: bundleID!) print("venderId set : key \(bundleID) and value: \(venderId)") } catch let error { print("Could not save data in Keychain : \(error)") } } func getVenderId() -> String { let keychain = Keychain(service: bundleID!) let token : String = try! keychain.get(bundleID!)! return token }