web-dev-qa-db-fra.com

Identifier de manière unique un utilisateur iOS

J'aimerais créer un compte d'utilisateur sur le serveur pour les nouveaux utilisateurs d'une application, mais j'aimerais également ne pas demander à l'utilisateur de saisir quoi que ce soit. Idéalement, j'aimerais que ce soit automatique, comme avec Game Center.

Mais je me demande si c'est possible. Y a-t-il quelque chose que je puisse utiliser pour identifier de manière unique l'utilisateur? Il est très peu probable que je puisse trouver l'identifiant Apple. En outre, l'ID de périphérique identifie de manière unique le périphérique, pas l'utilisateur, il serait donc inutile si l'utilisateur possède plus de périphériques ...

Y a-t-il autre chose que je peux utiliser?

À propos de la confidentialité - Je ne veux rien découvrir derrière le dos de l'utilisateur. Je n'ai absolument aucun problème à demander à l'utilisateur l'accès à ses informations (et s'il existe une API qui m'accorde ces informations, ce serait bien si l'API le demande elle-même). Comme Steve Jobs lui-même l'a dit, c'est la protection de la vie privée: obliger les applications à demander la permission à l'utilisateur avant de faire quoi que ce soit avec leurs données privées.

36
rid

La solution correcte consiste à utiliser iCloud Key-Value Store , où vous pouvez stocker un ID utilisateur unique sans nécessiter d'authentification ni d'informations utilisateur telles qu'une adresse électronique. 

Le résultat final est un UUID aléatoire (rien qui identifie réellement l'utilisateur), différent pour chaque utilisateur, mais ayant la même valeur pour plusieurs appareils enregistrés sur le même compte iTunes.

Nous définissons un champ dans notre magasin iCloud KV, appelons-le ID utilisateur. Lorsque l'application est lancée, nous vérifions d'abord l'ID utilisateur. S'il y en a un, nous avons tous défini l'identifiant unique de notre utilisateur. Sinon, c'est la première fois que nous courons pour cet utilisateur. Nous générons un UUID aléatoire et le stockons dans le magasin KV sous l'ID utilisateur. C'est tout ce qu'on peut en dire.

Notre expérience montre que cet UUID est unique par compte iTunes. Si vos utilisateurs finaux utilisent le partage des familles, différents comptes seront attribués à ces comptes (ce qui peut être souhaitable ou non, mais vous ne pouvez rien y faire). N'importe quel nombre d'appareils lancés sous le même compte iTunes verra le même UUID.

Cette approche est totalement légitime et devrait être approuvée par Apple sans aucun problème.

Évidemment, vous devez activer le magasin iCloud Key-Value sur Xcode sous Capacités. Il vous suffit d’activer le commutateur iCloud.

Voici une classe simple qui implémente ce concept dans Objective-C:

@implementation EEUserID

+ (NSUUID *) getUUID
{
    NSUUID *uuid = nil;
    NSString *uuidString = [[NSUbiquitousKeyValueStore defaultStore] stringForKey: @"EEUserID"];
    if (uuidString == nil)
    {
        // This is our first launch for this iTunes account, so we generate random UUID and store it in iCloud:
        uuid = [NSUUID UUID];
        [[NSUbiquitousKeyValueStore defaultStore] setString: uuid.UUIDString forKey: @"EEUserID"];
        [[NSUbiquitousKeyValueStore defaultStore] synchronize];
    }
    else
    {
        uuid = [[NSUUID alloc] initWithUUIDString: uuidString];
    }

    return uuid;
}

+ (NSString *) getUUIDString
{
    NSUUID *uuid = [self getUUID];
    if (uuid != nil)
        return uuid.UUIDString;
    else
        return nil;
}

+ (void) load
{
    // get changes that might have happened while this
    // instance of your app wasn't running
    [[NSUbiquitousKeyValueStore defaultStore] synchronize];
}

@end

Et pour le fichier d'en-tête:

#import <Foundation/Foundation.h>

@interface EEUserID : NSObject

+ (NSUUID *) getUUID;
+ (NSString *) getUUIDString;

@end

Pour utiliser, tout ce que vous avez à faire est d’appeler:

NSString *uniqueIDForiTunesAccount = [EEUserID getUUIDString];

Prendre plaisir.

23
ldoogy

Générez un UUID avec ceci:

NSString *UUID() {
    CFUUIDRef cfuuid = CFUUIDCreate(NULL); 
    NSString *uuid =  (__bridge_transfer NSString *)CFUUIDCreateString(NULL, cfuuid); 
    CFRelease(cfuuid);
    return uuid;
}

Apple n’a jamais déconseillé ni désapprouvé les choses. En fait, c’est la façon dont elles vous suggèrent de le faire. Stockez l'UUID généré dans le trousseau et il y sera, même si l'utilisateur désinstalle et réinstalle votre application. L'UUID est unique pour le périphérique et l'heure à laquelle il a été généré.

Vous pouvez ensuite utiliser différents schémas pour que les utilisateurs regroupent leurs périphériques - iCloud ou une sorte de clé fournie par le serveur.

Bonne chance!

Addition:

Voici comment je le stocke dans le trousseau, en utilisant l'uuid comme nom d'utilisateur et en générant un mot de passe aléatoire:

uuid = UUID();
[keychainItemWrapper setObject:uuid forKey:(__bridge_transfer id)kSecAttrAccount];
NSString *pass_token = randomString(10);
[keychainItemWrapper setObject:pass_token forKey:(__bridge_transfer id)kSecValueData];

Notez que tout cela peut être fait sans aucune intervention de l'utilisateur.

Mise à jour:

MCSMKeychainItem a une excellente solution pour la génération et le stockage d’UUID avec [MCSMApplicationUUIDKeychainItem applicationUUID]. La bibliothèque a aussi [MCSMGenericKeychainItem genericKeychainItemWithService:service username:username password:password]. Ensemble, ces fonctions s’occupent de tout ce qui est mentionné ci-dessus. Facile à installer avec CocoaPods aussi.

22
Erik

Radu

Excellente question. Nous avons résolu le problème que vous décrivez en intégrant Urban Airship (urbanairship.com) dans nos applications. Urban Airship offre une panoplie de fonctionnalités permettant de prendre en charge les achats intégrés, la validation de reçus, la récupération d'abonnement, la livraison de contenu et la notification push Apple.

L'un des avantages de Urban Airship réside dans sa capacité à identifier un "utilisateur", non pas un appareil, mais un "utilisateur" par adresse électronique. Ce n'est pas vraiment une "fonctionnalité" annoncée ... plutôt un sous-produit de la fonctionnalité prévue.

Voici ce que nous avons trouvé et comment nous pouvons utiliser Urban Airship pour résoudre le problème que vous avez.

Lorsqu'un utilisateur installe votre application à laquelle Urban Urban est intégré, UA génère en quelque sorte un numéro de type UDID qui, pour le moment, identifie simplement le périphérique. 

Toutefois, si vous exploitez les composants de récupération d'abonnement d'Urban Airship, vous pouvez demander à l'utilisateur de saisir une adresse électronique. Une fois que l'utilisateur a saisi son adresse électronique sur le premier appareil ..., cet identifiant généré devient sa principale méthode d'identification de l'utilisateur et est associé à cette adresse électronique. Quand ils saisiront leur adresse électronique sur les appareils suivants, Urban Airship déclenchera un processus de validation de l’e-mail. Une fois que l'utilisateur a terminé le processus de validation, il met à jour l'ID sur le nouveau périphérique afin qu'il corresponde à l'ID du premier périphérique, etc. Le meilleur dans tout ça, c'est ... tout est magique! Vous intégrez simplement les composants et demandez à l'utilisateur de saisir son adresse électronique. Vous devriez pouvoir tout faire fonctionner en moins d'une heure.

Il offre également une fonctionnalité permettant à l'utilisateur de modifier l'adresse électronique associée à tous ses appareils.

Nous avons effectivement mis en œuvre et cela fonctionne très bien!

REMARQUE: à compter du 1er juillet 2013, Urban Airship déconseille la fonctionnalité d'abonnement et de récupération.

4
radesix

Générer un UUID comme suggéré par Erik est une solution solide. La seule (petite) mise en garde peut être que dans le cas d'une restauration complète d'iDevice, le trousseau sera également effacé. L'application générera un nouvel UUID dans ce scénario et iDevice ne peut plus être associé à un utilisateur existant.

Une autre approche pour identifier un iDevice de manière unique consiste à générer un identifiant unique basé sur l'adresse MAC de l'interface réseau et à le combiner avec l'identifiant du bundle d'applications. Cette méthode génère un identifiant unique spécifique à l'application et durable. Cela ne changera pas lorsque l'iDevice est effacé, restauré ou lorsque l'application est supprimée et réinstallée. De ce fait, il n'est pas nécessaire de stocker cet identifiant dans le trousseau.

Heureusement, certaines personnes ont déjà créé une petite bibliothèque pour y parvenir. Le code peut être trouvé sur GitHub:

https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5

1
Bas Peters

Que diriez-vous d'utiliser Game Center et iCloud ensemble pour identifier un utilisateur?

Il est moins probable qu'un utilisateur ne joue pas et ne synchronise pas ses données.

0
Mickey

Vous pouvez utiliser des solutions tierces telles que SECUREUDID consultez également this

0
msk

Aujourd'hui, notre application a été rejetée en raison de l'identification de l'utilisateur du Game Center. C'est dans les directives de l'App Store: https://developer.Apple.com/appstore/resources/approval/guidelines.html

Vous ne pouvez pas utiliser un identifiant Game Center unique au format G :.

Pour nous, le seul moyen consiste maintenant à utiliser l'intégration Facebook iOS6.

MISE À JOUR: Notre nouvelle version avec ouverture automatique de session FB a passé le processus de révision et est disponible sur App Store (Slovni Duel). Utilise également l'abonnement inApp lié au profil FB.

0
Lubomir

Ce n'est pas une solution absolument sûre (et ne fonctionne que lorsque iCloud est activé), mais il est très facile à implémenter: Générez un ID unique une fois (comme UUID) et stockez-le dans iCloud key-value-storage.

Le seul problème est que les utilisateurs expérimentés savent comment supprimer du contenu de iCloud.

Pour empêcher l'utilisateur de simplement modifier l'ID unique stocké dans iCloud en un autre ID, vous pouvez ajouter une sorte de secret.

0
miho

Une alternative à la suggestion d'Erik est une bibliothèque tierce appelée OpenUDID . Vous pouvez générer un identifiant unique pour chaque appareil, et c'est très simple: 

#include "OpenUDID.h"
NSString* openUDID = [OpenUDID value];
0
Anthony