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!

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

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


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)

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.


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")!)

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
        }

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)
        }
    }
}

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

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.


30
NSUUID (). UUIDString da ci nowy ciąg za każdym razem
Eric
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.