Jak uzyskać unikalny identyfikator urządzenia w Swift?

181

Jak mogę uzyskać unikalny identyfikator urządzenia w Swift?

Potrzebuję identyfikatora do użycia w bazie danych i jako klucz API dla mojej usługi internetowej w mojej aplikacji społecznościowej. Coś do śledzenia codziennego użytkowania tego urządzenia i ograniczania zapytań do bazy danych.

Dzięki!

Użytkownik
źródło

Odpowiedzi:

386

Możesz użyć tego (Swift 3):

UIDevice.current.identifierForVendor!.uuidString

W przypadku starszych wersji:

UIDevice.currentDevice().identifierForVendor

lub jeśli chcesz ciąg:

UIDevice.currentDevice().identifierForVendor!.UUIDString


Nie ma już sposobu jednoznacznej identyfikacji urządzenia po odinstalowaniu aplikacji przez użytkownika. Dokumentacja mówi:

Wartość w tej właściwości pozostaje taka sama, gdy aplikacja (lub inna aplikacja tego samego dostawcy) jest zainstalowana na urządzeniu z systemem iOS. Wartość zmienia się, gdy użytkownik usunie wszystkie aplikacje tego dostawcy z urządzenia, a następnie ponownie zainstaluje jedną lub więcej z nich.


Możesz również przeczytać ten artykuł Mattta Thompsona, aby uzyskać więcej informacji:
http://nshipster.com/uuid-udid-unique-identifier/

Aktualizacja do Swift 4.1 , będziesz musiał użyć:

UIDevice.current.identifierForVendor?.uuidString
Atomix
źródło
może dodać .UUIDString, aby można go było faktycznie wysłać na serwer?
Daniel Galasko,
2
Tak. Uznałem, że to oczywiste, ale zawarłem to w odpowiedzi.
Atomix
19
Po odinstalowaniu aplikacji ten numer nie jest już taki sam. Czy istnieje sposób na śledzenie urządzenia nawet po odinstalowaniu aplikacji?
jmcastel,
5
lepszym pytaniem jest, jeśli usuniesz je po odinstalowaniu, w jaki sposób usuniesz ich konto na serwerze, gdy identyfikator nie jest już używany?
Jason G
2
@UmairAfzal Wiele rzeczy nie działa w symulatorze. Czy wypróbowałeś to na prawdziwym urządzeniu?
Atomix
10

Możesz użyć właściwości publicznej identifierForVendor obecnej w klasie UIDevice

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

EDYCJA Swift 3:

UIDevice.current.identifierForVendor!.uuidString

EDYCJA KOŃCOWA

Zrzut ekranu dla hierarchii właściwości

Jayprakash Dubey
źródło
3
To tylko kopia odpowiedzi @Atomix
Ashley Mills,
10

Dla Swift 3.X najnowszego działającego kodu, łatwe użytkowanie;

   let deviceID = UIDevice.current.identifierForVendor!.uuidString
   print(deviceID)
SwiftDeveloper
źródło
3
Zmienia się za każdym razem, gdy użyjesz odinstaluj i zainstaluj aplikację ponownie.
iPeter
7
To tylko kopia odpowiedzi @Atomix & JayprakasDubey
Ashley Mills,
10

Możesz użyć devicecheck (w Swift 4) dokumentacji 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" ...
    }
}

Typowe zastosowanie:

Zazwyczaj używasz interfejsów API DeviceCheck, aby upewnić się, że nowy użytkownik nie skorzystał już z oferty pod inną nazwą użytkownika na tym samym urządzeniu.

Potrzeba działania serwera:

Zobacz WWDC 2017 - sesja 702

więcej z artykułu Santosha Botre'a - Unikalny identyfikator dla urządzeń z systemem iOS

Powiązany serwer łączy ten token z kluczem uwierzytelniającym otrzymanym od Apple i wykorzystuje wynik do żądania dostępu do bitów na urządzenie.

iluvatar_GR
źródło
1
Jeśli dobrze to rozumiem, generowanie tokenów odbywa się za pomocą DCDevice.generateToken (), a każde wywołanie generuje unikalny, losowy token device_token. Stąd device_token nie jest trwały, ale efemeryczny. Nie rozumiem, w jaki sposób serwer może powiązać efemeryczny token z urządzeniem.
user1118764
@ user1118764 „Ustaw dwa bity - serwer aplikacji będzie odpowiedzialny za udostępnienie tego tokena i ustawienie wartości bitu”. czytaj więcej tutaj medium.com/@santoshbotre01/... a także tutaj z oficjalnej dokumentacji developer.apple.com/documentation/devicecheck/... oraz 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
źródło
2
Nie ma sensu, jeśli użytkownik usuwa aplikację, ponieważ błędy użytkownika są również usuwane podczas odinstalowywania aplikacji.
Rehan Ali
0
if (UIDevice.current.identifierForVendor?.uuidString) != nil
        {
            self.lblDeviceIdValue.text = UIDevice.current.identifierForVendor?.uuidString
        }
Davender Verma
źródło
1
Proszę skomentować swój kod i / lub szczegóły oferty oraz wyjaśnienie, w jaki sposób rozwiązuje to opublikowane pytanie.
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
źródło
-1

Wartość parametru identifierForVendor zmienia się, gdy użytkownik usuwa z urządzenia wszystkie aplikacje tego dostawcy, jeśli chcesz zachować unikalny identyfikator nawet dla kolejnych nowych instalacji, możesz spróbować użyć następującej funkcji

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
źródło
Kto kiedykolwiek głosował na tę odpowiedź, czy możesz wyjaśnić, dlaczego głosowała ona na dół? getCommonPartOfApplicationBundleID (), readFromKeyChain, saveToKeyChain to niestandardowe metody, które należy zaimplementować, nie uwzględniłem tych definicji, które nie powinny zwiększać rozmiaru odpowiedzi.
Shihab
Czy wartości przechowywane w pęku kluczy utrzymują się po odinstalowaniu aplikacji?
Anees
1
@ Tak, masz rację, moja odpowiedź jest nieprawidłowa w systemie iOS 10.3 Beta 2, automatycznie usuwa elementy pęku kluczy po odinstalowaniu aplikacji, jeśli nie ma aplikacji udostępnionych. W końcu będzie to takie samo zachowanie jak identifierForVendor metid.
Shihab,
-18

Próbowałem z

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

zamiast

let UUID = NSUUID().UUIDString

i to działa.

Matt
źródło
30
NSUUID (). UUIDString da ci nowy ciąg za każdym razem
Eric