Comment obtenir un identifiant d'appareil unique dans Swift?

186

Comment puis-je obtenir un identifiant unique d'appareil dans Swift?

J'ai besoin d'un identifiant à utiliser dans la base de données et comme clé API pour mon service Web dans mon application sociale. Quelque chose pour garder une trace de l'utilisation quotidienne de ces appareils et limiter ses requêtes à la base de données.

Merci!

Utilisateur
la source

Réponses:

394

Vous pouvez utiliser ceci (Swift 3):

UIDevice.current.identifierForVendor!.uuidString

Pour les anciennes versions:

UIDevice.currentDevice().identifierForVendor

ou si vous voulez une chaîne:

UIDevice.currentDevice().identifierForVendor!.UUIDString


Il n'y a plus de moyen d'identifier de manière unique un appareil après que l'utilisateur a désinstallé les applications. La documentation dit:

La valeur de cette propriété reste la même tant que l'application (ou une autre application du même fournisseur) est installée sur l'appareil iOS. La valeur change lorsque l'utilisateur supprime toutes les applications de ce fournisseur de l'appareil et réinstalle ensuite une ou plusieurs d'entre elles.


Vous pouvez également lire cet article de Mattt Thompson pour plus de détails:
http://nshipster.com/uuid-udid-unique-identifier/

Mise à jour pour Swift 4.1 , vous devrez utiliser:

UIDevice.current.identifierForVendor?.uuidString
Atomix
la source
peut-être ajouter .UUIDString afin qu'il puisse réellement être envoyé à un serveur?
Daniel Galasko
2
Ouaip. J'ai pensé que c'était la chose évidente à faire, mais je l'ai incluse dans la réponse.
Atomix
20
Après la désinstallation de l'application, ce numéro n'est plus le même. Existe-t-il un moyen de suivre un appareil même après la désinstallation de l'application?
jmcastel
5
meilleure question est, si elle est supprimée après la désinstallation, comment supprimer leur compte sur votre serveur lorsque l'ID n'est plus utilisé?
Jason G du
2
@UmairAfzal Beaucoup de choses ne fonctionnent pas dans le simulateur. L'avez-vous essayé sur le vrai appareil?
Atomix
10

Vous pouvez utiliser la propriété publique identifierForVendor présente dans la classe UIDevice

let UUIDValue = UIDevice.currentDevice().identifierForVendor!.UUIDString
        print("UUID: \(UUIDValue)")

MODIFIER Swift 3:

UIDevice.current.identifierForVendor!.uuidString

FIN DE LA MODIFICATION

Capture d'écran de la hiérarchie des propriétés

Jayprakash Dubey
la source
3
Ceci est juste une copie de la réponse @Atomix
Ashley Mills
10

Pour le dernier code de travail de Swift 3.X , utilisation facile;

   let deviceID = UIDevice.current.identifierForVendor!.uuidString
   print(deviceID)
SwiftDeveloper
la source
3
Cela change chaque fois que vous utilisez, désinstallez et réinstallez l'application.
iPeter
7
Ceci est juste une copie des réponses de @Atomix & JayprakasDubey
Ashley Mills
10

Vous pouvez utiliser devicecheck (dans Swift 4) Documentation Apple

func sendEphemeralToken() {
        //check if DCDevice is available (iOS 11)

        //get the **ephemeral** token
        DCDevice.current.generateToken {
        (data, error) in
        guard let data = data else {
            return
        }

        //send **ephemeral** token to server to 
        let token = data.base64EncodedString()
        //Alamofire.request("https://myServer/deviceToken" ...
    }
}

Utilisation typique:

En règle générale, vous utilisez les API DeviceCheck pour vous assurer qu'un nouvel utilisateur n'a pas déjà utilisé une offre sous un nom d'utilisateur différent sur le même appareil.

Besoins d'action du serveur:

Voir WWDC 2017 - Session 702

plus de l'article de Santosh Botre - Identifiant unique pour les appareils iOS

Votre serveur associé combine ce jeton avec une clé d'authentification que vous recevez d'Apple et utilise le résultat pour demander l'accès aux bits par appareil.

iluvatar_GR
la source
1
Si je comprends bien, la génération de jetons est effectuée à l'aide de DCDevice.generateToken (), et chaque appel génère un device_token unique et aléatoire. Par conséquent, device_token n'est pas persistant, mais éphémère. Ce que je ne comprends pas, c'est comment le serveur est capable d'associer un jeton éphémère à un appareil.
user1118764
@ user1118764 "Définir deux bits - Le serveur d'application sera responsable du partage de ce jeton et définira la valeur du bit." en savoir plus ici medium.com/@santoshbotre01/… et aussi ici de la documentation officielle developer.apple.com/documentation/devicecheck/… et 702 session developer.apple.com/videos/play/wwdc2017/702
iluvatar_GR
1

Swift 2.2

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    let userDefaults = NSUserDefaults.standardUserDefaults()

    if userDefaults.objectForKey("ApplicationIdentifier") == nil {
        let UUID = NSUUID().UUIDString
        userDefaults.setObject(UUID, forKey: "ApplicationIdentifier")
        userDefaults.synchronize()
    }
    return true
}

//Retrieve
print(NSUserDefaults.standardUserDefaults().valueForKey("ApplicationIdentifier")!)
n.by.n
la source
3
Il est inutile si l'utilisateur supprime l'application, car les valeurs par défaut de l'utilisateur sont également supprimées avec la désinstallation de l'application.
Rehan Ali
0

La valeur de identifierForVendor change lorsque l'utilisateur supprime toutes les applications de ce fournisseur de l'appareil, si vous souhaitez conserver l'ID unique même pour les nouvelles installations suivantes, vous pouvez essayer d'utiliser la fonction suivante

func vendorIdentifierForDevice()->String {
    //Get common part of Applicatoin Bundle ID, Note : getCommonPartOfApplicationBundleID is to be defined.
    let commonAppBundleID = getCommonPartOfApplicationBundleID()
    //Read from KeyChain using bunndle ID, Note : readFromKeyChain is to be defined.
    if let vendorID = readFromKeyChain(commonAppBundleID) {
        return vendorID
    } else {
        var vendorID = NSUUID().uuidString
        //Save to KeyChain using bunndle ID, Note : saveToKeyChain is to be defined.
        saveToKeyChain(commonAppBundleID, vendorID)
        return vendorID
    }
}
Shihab
la source
Qui a jamais voté contre cette réponse, pouvez-vous expliquer pourquoi cette réponse a voté à la baisse? getCommonPartOfApplicationBundleID (), readFromKeyChain, saveToKeyChain sont les méthodes personnalisées que vous devez implémenter, je n'ai pas inclus ces définitions en pensant ne pas augmenter la taille de la réponse.
Shihab le
Les valeurs stockées dans le trousseau persistent-elles lorsque l'application est désinstallée?
Anees
1
@Anees, vous avez raison, ma réponse n'est pas valide à partir d'iOS 10.3 Beta 2, elle supprime automatiquement les éléments du trousseau après la désinstallation de l'application, s'il n'y a pas d'applications partagées. Donc finalement ce sera le même comportement que le methid identifierForVendor.
Shihab
0
if (UIDevice.current.identifierForVendor?.uuidString) != nil
        {
            self.lblDeviceIdValue.text = UIDevice.current.identifierForVendor?.uuidString
        }
Davender Verma
la source
1
Veuillez commenter votre code et / ou les détails de l'offre et une explication de la façon dont cela résout la question posée.
RyanNerd
-1
class func uuid(completionHandler: @escaping (String) -> ()) {
    if let uuid = UIDevice.current.identifierForVendor?.uuidString {
        completionHandler(uuid)
    }
    else {
        // If the value is nil, wait and get the value again later. This happens, for example, after the device has been restarted but before the user has unlocked the device.
        // https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            uuid(completionHandler: completionHandler)
        }
    }
}
Joey
la source
-18

J'ai essayé avec

let UUID = UIDevice.currentDevice().identifierForVendor?.UUIDString

au lieu

let UUID = NSUUID().UUIDString

et il fonctionne.

Mat
la source
32
NSUUID (). UUIDString vous donnera une nouvelle chaîne à chaque fois
Eric