¿Cómo obtener una identificación de dispositivo única en Swift?

181

¿Cómo puedo obtener una identificación única de dispositivos en Swift?

Necesito una ID para usar en la base de datos y como clave API para mi servicio web en mi aplicación social. Algo para realizar un seguimiento del uso diario de estos dispositivos y limitar sus consultas a la base de datos.

¡Gracias!

Usuario
fuente

Respuestas:

386

Puedes usar esto (Swift 3):

UIDevice.current.identifierForVendor!.uuidString

Para versiones anteriores:

UIDevice.currentDevice().identifierForVendor

o si quieres una cadena:

UIDevice.currentDevice().identifierForVendor!.UUIDString


Ya no hay una manera de identificar de forma exclusiva un dispositivo después de que el usuario desinstaló las aplicaciones. La documentación dice:

El valor en esta propiedad permanece igual mientras la aplicación (u otra aplicación del mismo proveedor) está instalada en el dispositivo iOS. El valor cambia cuando el usuario elimina todas las aplicaciones de ese proveedor del dispositivo y posteriormente reinstala una o más de ellas.


También puede leer este artículo de Mattt Thompson para obtener más detalles:
http://nshipster.com/uuid-udid-unique-identifier/

Actualización para Swift 4.1 , deberá utilizar:

UIDevice.current.identifierForVendor?.uuidString
Atomix
fuente
tal vez agregue .UUIDString para que realmente se pueda enviar a un servidor?
Daniel Galasko
2
Sip. Supuse que eso era lo obvio, pero lo incluí en la respuesta.
Atomix
19
Después de desinstalar la aplicación, este número ya no es el mismo. ¿Hay alguna forma de rastrear un dispositivo incluso después de la desinstalación de la aplicación?
jmcastel
55
La mejor pregunta es, si se elimina después de la desinstalación, ¿cómo elimina su cuenta en su servidor cuando la ID ya no está en uso?
Jason G
2
@UmairAfzal Muchas cosas no funcionan en el simulador. ¿Lo probaste en el dispositivo real?
Atomix
10

Puede usar la propiedad pública identifierForVendor presente en la clase UIDevice

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

EDITAR Swift 3:

UIDevice.current.identifierForVendor!.uuidString

EDICIÓN FINAL

Captura de pantalla para la jerarquía de propiedades

Jayprakash Dubey
fuente
3
Esta es solo una copia de la respuesta de @Atomix
Ashley Mills
10

Para el último código de trabajo de Swift 3.X , uso fácil;

   let deviceID = UIDevice.current.identifierForVendor!.uuidString
   print(deviceID)
SwiftDeveloper
fuente
3
Esto cambia cada vez que usa la desinstalación e instala la aplicación nuevamente.
iPeter
77
Esta es solo una copia de las respuestas de @Atomix y JayprakasDubey
Ashley Mills
10

Puede usar la comprobación de dispositivos (en Swift 4) Documentación de 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" ...
    }
}

Uso típico:

Por lo general, utiliza las API de DeviceCheck para asegurarse de que un nuevo usuario no haya canjeado una oferta con un nombre de usuario diferente en el mismo dispositivo.

La acción del servidor necesita:

Ver WWDC 2017 - Sesión 702

más del artículo de Santosh Botre - Identificador único para dispositivos iOS

Su servidor asociado combina este token con una clave de autenticación que recibe de Apple y utiliza el resultado para solicitar acceso a los bits por dispositivo.

iluvatar_GR
fuente
1
Si lo entiendo correctamente, la generación de tokens se realiza utilizando DCDevice.generateToken (), y cada llamada genera un dispositivo único y aleatorio. Por lo tanto, device_token no es persistente, sino efímero. Lo que no entiendo es cómo el servidor puede asociar un token efímero con un dispositivo.
user1118764
@ user1118764 "Establecer dos bits: el servidor de aplicaciones será responsable de compartir este token y establecer el valor de bit". lea más aquí medium.com/@santoshbotre01/… y también aquí de la documentación oficial developer.apple.com/documentation/devicecheck/… y 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
fuente
2
Es inútil si el usuario elimina la aplicación porque los valores predeterminados del usuario también se eliminan con la desinstalación de la aplicación.
Rehan Ali
0
if (UIDevice.current.identifierForVendor?.uuidString) != nil
        {
            self.lblDeviceIdValue.text = UIDevice.current.identifierForVendor?.uuidString
        }
Davender Verma
fuente
1
Comente su código y / u ofrezca detalles y una explicación de cómo esto resuelve la pregunta publicada.
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
fuente
-1

El valor de identifierForVendor cambia cuando el usuario elimina todas las aplicaciones de ese proveedor del dispositivo, si desea mantener la ID única incluso para las nuevas instalaciones posteriores, puede intentar usar la siguiente función

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
fuente
¿Quién votó en contra de esta respuesta? ¿Puede explicar por qué votó en contra? getCommonPartOfApplicationBundleID (), readFromKeyChain, saveToKeyChain son los métodos personalizados que necesita implementar, no he incluido esas definiciones pensando no aumentar el tamaño de la respuesta.
Shihab
¿Los valores almacenados en el llavero persisten cuando se desinstala la aplicación?
Anees
1
@Anees, tiene razón, mi respuesta no es válida desde iOS 10.3 Beta 2, elimina automáticamente los elementos de llavero después de la desinstalación de la aplicación, si no hay aplicaciones compartidas. Así que finalmente será el mismo comportamiento que identifierForVendor methid.
Shihab
-18

He intentado con

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

en lugar

let UUID = NSUUID().UUIDString

y funciona.

Mate
fuente
30
NSUUID (). UUIDString le dará una nueva cadena cada vez
Eric