web-dev-qa-db-fra.com

Pourquoi iOS obtient-il un nouvel identifiantForVendor lorsque l'application est mise à jour?

Chaque fois que mon application est mise à jour depuis l'App Store, un petit nombre d'utilisateurs obtiennent un nouveau identifierForVendor pour une raison quelconque. Mes utilisateurs ne s'inscrivent pas ou ne se connectent pas. Ils sont tous anonymes, je dois donc les séparer par leur identifiant de fournisseur.

J'ai considéré qu'il pouvait y avoir un manque d'espace sur certains appareils, ce qui entraînait la suppression et la réinstallation de l'application, mais ce n'est pas le cas puisque dans la dernière mise à jour, un de mes amis disposait de plus de 2 Go d'espace libre.

Je sais que le identifierForVendor est modifié pour un utilisateur qui supprime et réinstalle l'application. Mais ce n'est pas le cas ici, car l'application vient d'être mise à jour.

Quel pourrait être le problème? Ce qui est étrange, c’est que cela n’est pas encore arrivé pour les appareils de l’équipe de développement. Ou encore, il y a encore des utilisateurs qui n'ont pas rencontré ce bogue après d'innombrables mises à jour d'applications, mises à jour de systèmes d'exploitation, etc. Cela ne concerne qu'un petit pourcentage des utilisateurs. Tous les utilisateurs sont iOS7 + et cela se produit pour différents modèles d'appareils et versions iOS.

J'utilise ce code pour obtenir leur identifiant:

static let DeviceId = UIDevice.currentDevice().identifierForVendor.UUIDString

Ensuite, je les enregistre dans NSUserDefaults:

NSUserDefaults.standardUserDefaults().setBool(true, forKey: "User" + DeviceId)
NSUserDefaults.standardUserDefaults().synchronize()

Ensuite, je vérifie si l'utilisateur existe, à chaque nouvelle connexion:

static func doesUserExist() -> Bool {
    var userDefaultValue: AnyObject? = NSUserDefaults.standardUserDefaults().valueForKey("User" + DeviceId)

    if defaultValue == true {
        println("Userdefaults already has this guy, moving on")
        FirstTime = false
        return true
    } else {
        println("First time in the app!")
        FirstTime = true
        return false
    }
}

Si l'utilisateur existe, il lance le processus de connexion. Si l'utilisateur n'existe pas, il affiche le processus d'inscription. J'utilise Parse.com comme backend et le deviceID est utilisé comme nom d'utilisateur. Lorsque ce petit nombre d'utilisateurs rencontre ce bogue, je vois un nouveau nom d'utilisateur et un nouveau compte créé.

13
Esqarrouth

Un bug affectant le calcul de identifierForVendor lors de la mise à jour d'une application depuis l'App Store entre mai et juillet. Apple a affirmé avoir déjà résolu le problème et qu'une nouvelle mise à jour devrait restaurer la valeur d'origine avant la date critique. Référence: https://openradar.appspot.com/22677034

Notez que certains utilisateurs ont encore observé ce problème, même après des mises à jour plusieurs semaines après juillet. Donc, il est toujours possible que le bogue soit toujours présent ou qu'il puisse refaire surface à tout moment. Donc, si vous utilisez ces données dans le cadre de votre cryptage, le mieux est de les enregistrer dans le trousseau. 

7
chalcopyrite

Je ne comprends pas pourquoi vous enregistrez d'abord l'IFV dans NSUserDefaults, puis vérifiez si cette clé existe. Je pense que tu devrais...

1) vérifiez d'abord NSUserDefaults pour voir si la clé IFV que vous avez créée existe

2) si la clé NSUserDefaults existe, faites-en ce que vous avez besoin, le profil de cet utilisateur existe déjà

3) si la clé n'existe pas, obtenez l'IFV et enregistrez-le dans NSUserDefaults

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

if ([defaults valueForKey:@"IFV"]) {
    //this user already exists, do what you need to do next with IFV
}

else{
    //this is their first time using the app
    NSString *ifvString = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    [defaults setValue:ifvString forKey:@"IFV"];

    //do what you need to do next with IFV
}
0
George Steiner

Enregistrez le vendorID dans le KeyChain, qui persistera après la suppression ou toute mise à jour.

-(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;
}

Disclaimer: J'ai pris le code d'une autre SO réponse il y a quelque temps, alors Je ne me souviens plus qui louer, mais finalement ce n'est pas moi
@Jonny a trouvé le source

0
dogsgod