ios deprecated uidevice

ios - UIDevice uniqueIdentifier Deprecated-¿Qué hacer ahora?



(30)

Acaba de salir a la luz que la propiedad UIDevice uniqueIdentifier está obsoleta en iOS5 y superior. Ningún método o propiedad alternativa parece estar disponible o próximo.

Muchas de nuestras aplicaciones existentes dependen en gran medida de esta propiedad para identificar de manera única un dispositivo en particular. ¿Alguien puede sugerir alguna idea de cómo podemos manejar este problema en el futuro?

La sugerencia de la documentación es ...

Consideraciones Especiales

No utilice la propiedad uniqueIdentifier. Para crear un identificador único específico para su aplicación, puede llamar a la función CFUUIDCreate para crear un UUID y escribirlo en la base de datos predeterminada usando la clase NSUserDefaults .

Sin embargo, este valor no será el mismo si un usuario desinstala y vuelve a instalar la aplicación.



Basado en el enlace propuesto por @moonlight, hice varias pruebas y parece ser la mejor solución. Como @DarkDust dice que el método va a verificar en0 que siempre está disponible.
Hay 2 opciones:
uniqueDeviceIdentifier (MD5 de MAC + CFBundleIdentifier)
y uniqueGlobalDeviceIdentifier (MD5 de MAC), siempre devuelven los mismos valores.
A continuación las pruebas que he realizado (con el dispositivo real):

#import "UIDevice+IdentifierAddition.h" NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]); NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);

XXXX21f1f19edff198e2a2356bf4XXXX - (WIFI) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (WIFI) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (3G) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (3G) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (GPRS) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (GPRS) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (modo AirPlane) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (modo AirPlane) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (Wi-Fi) después de quitar y reinstalar la aplicación XXXX7dc3c577446a2bcbd77935bdXXXX (Wi-Fi) después de quitar e instalar la aplicación

Espero que sea útil.

EDITAR:
Como han señalado otros, esta solución en iOS 7 ya no es útil, ya que uniqueIdentifier ya no está disponible y la consulta de la dirección MAC ahora siempre devuelve 02: 00: 00: 00: 00: 00


Crea tu propio UUID y luego guárdalo en el llavero. Por lo tanto, persiste incluso cuando su aplicación se desinstala. En muchos casos, también persiste incluso si el usuario migra entre dispositivos (por ejemplo, copia de seguridad completa y restauración a otro dispositivo).

Efectivamente, se convierte en un identificador de usuario único en lo que a usted respecta. (incluso mejor que el identificador del dispositivo ).

Ejemplo:

Estoy definiendo un método personalizado para crear un UUID como:

- (NSString *)createNewUUID { CFUUIDRef theUUID = CFUUIDCreate(NULL); CFStringRef string = CFUUIDCreateString(NULL, theUUID); CFRelease(theUUID); return [(NSString *)string autorelease]; }

Luego puede almacenarlo en KEYCHAIN en el primer lanzamiento de su aplicación. Para que después del primer lanzamiento, simplemente podamos usarlo desde el llavero, sin necesidad de regenerarlo. La razón principal para usar el llavero para almacenar es: cuando configura el UUID en el llavero, persistirá incluso si el usuario desinstala completamente la aplicación y luego la vuelve a instalar. . Entonces, esta es la forma permanente de almacenarlo, lo que significa que la clave será única en todo momento.

#import "SSKeychain.h" #import <Security/Security.h>

En el lanzamiento de la aplicación incluye el siguiente código:

// getting the unique key (if present ) from keychain , assuming "your app identifier" as a key NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"]; if (retrieveuuid == nil) { // if this is the first time app lunching , create key for device NSString *uuid = [self createNewUUID]; // save newly created key to Keychain [SSKeychain setPassword:uuid forService:@"your app identifier" account:@"user"]; // this is the one time process }

Descargue los archivos SSKeychain.m y .h de sskeychain y arrastre los archivos SSKeychain.m y .h a su proyecto y agregue "Security.framework" a su proyecto. Para usar UUID después simplemente usa:

NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];



El siguiente código ayuda a obtener UDID:

udid = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; NSLog(@"UDID : %@", udid);


Es posible que desee considerar el uso de OpenUDID que es un reemplazo OpenUDID para el UDID desuso.

Básicamente, para coincidir con el UDID , se requieren las siguientes funciones:

  1. Único o suficientemente único (una colisión de baja probabilidad es probablemente muy aceptable)
  2. Persistencia en reinicios, restauraciones, desinstalaciones.
  3. disponible en aplicaciones de diferentes proveedores (útil para adquirir usuarios a través de redes CPI) -

OpenUDID cumple con lo anterior e incluso tiene un mecanismo OpenUDID para su posterior consideración.

Verifique http://OpenUDID.org que apunta al GitHub correspondiente. ¡Espero que esto ayude!

Como nota al margen, me alejaría de cualquier alternativa de dirección MAC. Si bien la dirección MAC aparece como una solución tentadora y universal, asegúrese de que esta fruta de baja altura esté envenenada. La dirección MAC es muy sensible, y Apple puede desaprobar el acceso a esta antes de que pueda decir "ENVIAR ESTA APLICACIÓN" ... la dirección de red MAC se utiliza para autenticar ciertos dispositivos en redes privadas (WLAN) u otras redes privadas virtuales. redes (VPNs). .. es incluso más sensible que el antiguo UDID!


Este es el código que estoy usando para obtener ID tanto para iOS 5 como para iOS 6, 7:

- (NSString *) advertisingIdentifier { if (!NSClassFromString(@"ASIdentifierManager")) { SEL selector = NSSelectorFromString(@"uniqueIdentifier"); if ([[UIDevice currentDevice] respondsToSelector:selector]) { return [[UIDevice currentDevice] performSelector:selector]; } } return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; }


Estoy seguro de que Apple ha molestado a muchas personas con este cambio. Desarrollé una aplicación de contabilidad para iOS y tengo un servicio en línea para sincronizar los cambios realizados en diferentes dispositivos. El servicio mantiene una base de datos de todos los dispositivos y los cambios que deben propagarse a ellos. Por lo tanto, es importante saber qué dispositivos son cuáles. Estoy siguiendo el rastro de los dispositivos usando el identificador único de UIDevice y para lo que vale, aquí están mis pensamientos.

  • ¿Generar un UUID y almacenar en los valores predeterminados del usuario? No es bueno porque esto no persiste cuando el usuario elimina la aplicación. Si se vuelven a instalar más tarde, el servicio en línea no debería crear un nuevo registro de dispositivo, eso desperdiciaría recursos en el servidor y daría una lista de dispositivos que contienen el mismo dos o más veces. Los usuarios verían más de un "iPhone de Bob" en la lista si volvieran a instalar la aplicación.

  • ¿Generar un UUID y almacenar en el llavero? Este era mi plan, ya que persiste incluso cuando la aplicación se desinstala. Pero cuando se restaura una copia de seguridad de iTunes a un nuevo dispositivo iOS, el llavero se transfiere si la copia de seguridad está cifrada. Esto podría llevar a dos dispositivos que contengan la misma ID de dispositivo si los dispositivos antiguos y nuevos están en servicio. Estos deben aparecer como dos dispositivos en el servicio en línea, incluso si el nombre del dispositivo es el mismo.

  • ¿Generar un hash la dirección MAC y la identificación del paquete? Esto parece la mejor solución para lo que necesito. Al hacer hash con el ID de paquete, el ID de dispositivo generado no permitirá que se rastree el dispositivo en todas las aplicaciones y obtengo un ID único para la combinación de dispositivo + dispositivo.

Es interesante notar que la documentación de Apple se refiere a la validación de recibos de la tienda de aplicaciones de Mac al calcular un hash de la dirección MAC del sistema más la identificación y la versión del paquete. Así que esto parece permitido por la política, ya sea que pase a través de la revisión de la aplicación que todavía no sé.


La dirección MAC puede ser falsificada, lo que hace que este enfoque sea inútil para vincular contenido a usuarios específicos o implementar características de seguridad como listas negras.

Después de una investigación adicional, me parece que nos quedamos sin una alternativa adecuada a partir de ahora. Espero seriamente que Apple reconsidere su decisión.

Tal vez sería una buena idea enviar un correo electrónico a Apple sobre este tema y / o presentar una solicitud de error / función sobre esto, ya que tal vez ni siquiera estén al tanto de las consecuencias para los desarrolladores.


No use estas bibliotecas - libOmnitureAppMeasurement, usa unIdentificador único que Apple ya no soporta


Parece que para iOS 6, Apple recomienda que uses la clase NSUUID .

Del mensaje ahora en los documentos uniqueIdentifier para la propiedad uniqueIdentifier :

En desuso en iOS 5.0. Utilice la propiedad identifierForVendor de esta clase o la propiedad advertisingIdentifier de la clase ASIdentifierManager, según corresponda, o use el método UUID de la clase NSUUID para crear un UUID y escríbalo en la base de datos predeterminada del usuario.


Puede ayudar: use el código de abajo, siempre será Único, excepto que borre (Formato) su dispositivo.

UIDevice *myDevice=[UIDevice currentDevice]; NSString *UUID = [[myDevice identifierForVendor] UUIDString];



Puede utilizar su alternativa para Apple UDID ya. Kind guy gekitz escribió una categoría en UIDevice que generará algún tipo de UDID basado en la dirección mac del dispositivo y el identificador del paquete.

Puedes encontrar el código en github


Puedes usar

NSString *sID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

Que es único para el dispositivo en todas las aplicaciones.


Quizás puedas usar:

[UIDevice currentDevice].identifierForVendor.UUIDString

La documentación de Apple describe identifierForVender de la siguiente manera:

El valor de esta propiedad es el mismo para las aplicaciones que provienen del mismo proveedor que se ejecuta en el mismo dispositivo. Se devuelve un valor diferente para las aplicaciones en el mismo dispositivo que provienen de diferentes proveedores, y para las aplicaciones en diferentes dispositivos sin importar el proveedor.


Si alguien se topa con esta pregunta, al buscar una alternativa. He seguido este enfoque en la clase IDManager . Esta es una colección de diferentes soluciones. KeyChainUtil es un envoltorio para leer de llavero. También puede usar la hashed MAC address como un tipo de ID única.

/* Apple confirmed this bug in their system in response to a Technical Support Incident      request. They said that identifierForVendor and advertisingIdentifier sometimes      returning all zeros can be seen both in development builds and apps downloaded over the      air from the App Store. They have no work around and can''t say when the problem will be fixed. */ #define kBuggyASIID @"00000000-0000-0000-0000-000000000000" + (NSString *) getUniqueID { if (NSClassFromString(@"ASIdentifierManager")) { NSString * asiID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; if ([asiID compare:kBuggyASIID] == NSOrderedSame) { NSLog(@"Error: This device return buggy advertisingIdentifier."); return [IDManager getUniqueUUID]; } else { return asiID; } } else { return [IDManager getUniqueUUID]; } } + (NSString *) getUniqueUUID { NSError * error; NSString * uuid = [KeychainUtils getPasswordForUsername:kBuyassUser andServiceName:kIdOgBetilngService error:&error]; if (error) { NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]); return nil; } if (!uuid) { DLog(@"No UUID found. Creating a new one."); uuid = [IDManager GetUUID]; uuid = [Util md5String:uuid]; [KeychainUtils storeUsername:USER_NAME andPassword:uuid forServiceName:SERVICE_NAME updateExisting:YES error:&error]; if (error) { NSLog(@"Error getting unique UUID for this device! %@", [error localizedDescription]); return nil; } } return uuid; } /* NSUUID is after iOS 6. */ + (NSString *)GetUUID { CFUUIDRef theUUID = CFUUIDCreate(NULL); CFStringRef string = CFUUIDCreateString(NULL, theUUID); CFRelease(theUUID); return [(NSString *)string autorelease]; } #pragma mark - MAC address // Return the local MAC addy // Courtesy of FreeBSD hackers email list // Last fallback for unique identifier + (NSString *) getMACAddress { int mib[6]; size_t len; char *buf; unsigned char *ptr; struct if_msghdr *ifm; struct sockaddr_dl *sdl; mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; if ((mib[5] = if_nametoindex("en0")) == 0) { printf("Error: if_nametoindex error/n"); return NULL; } if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { printf("Error: sysctl, take 1/n"); return NULL; } if ((buf = malloc(len)) == NULL) { printf("Error: Memory allocation error/n"); return NULL; } if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { printf("Error: sysctl, take 2/n"); free(buf); // Thanks, Remy "Psy" Demerest return NULL; } ifm = (struct if_msghdr *)buf; sdl = (struct sockaddr_dl *)(ifm + 1); ptr = (unsigned char *)LLADDR(sdl); NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)]; free(buf); return outstring; } + (NSString *) getHashedMACAddress { NSString * mac = [IDManager getMACAddress]; return [Util md5String:mac]; } + (NSString *)md5String:(NSString *)plainText { if(plainText == nil || [plainText length] == 0) return nil; const char *value = [plainText UTF8String]; unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH]; CC_MD5(value, strlen(value), outputBuffer); NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){ [outputString appendFormat:@"%02x",outputBuffer[count]]; } NSString * retString = [NSString stringWithString:outputString]; [outputString release]; return retString; }


También sugeriría cambiar de uniqueIdentifier a github (2 categorías simples realmente) que utilizan la dirección MAC del dispositivo junto con el Identificador de paquete de aplicaciones para generar una ID única en sus aplicaciones que se puede usar como un reemplazo UDID.

Tenga en cuenta que, a diferencia del UDID, este número será diferente para cada aplicación.

Simplemente necesita importar las categorías NSString y UIDevice incluidas y llamar a [[UIDevice currentDevice] uniqueDeviceIdentifier] así:

#import "UIDevice+IdentifierAddition.h" #import "NSString+MD5Addition.h" NSString *iosFiveUDID = [[UIDevice currentDevice] uniqueDeviceIdentifier]

Lo puedes encontrar en Github aquí:

github

Aquí están las categorías (solo los archivos .m - verifique el proyecto github para los encabezados):

UIDevice + IdentifierAddition.m

#import "UIDevice+IdentifierAddition.h" #import "NSString+MD5Addition.h" #include <sys/socket.h> // Per msqr #include <sys/sysctl.h> #include <net/if.h> #include <net/if_dl.h> @interface UIDevice(Private) - (NSString *) macaddress; @end @implementation UIDevice (IdentifierAddition) //////////////////////////////////////////////////////////////////////////////// #pragma mark - #pragma mark Private Methods // Return the local MAC addy // Courtesy of FreeBSD hackers email list // Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb. - (NSString *) macaddress{          int mib[6];     size_t len;     char *buf;     unsigned char *ptr;     struct if_msghdr *ifm;     struct sockaddr_dl *sdl;          mib[0] = CTL_NET;     mib[1] = AF_ROUTE;     mib[2] = 0;     mib[3] = AF_LINK;     mib[4] = NET_RT_IFLIST;          if ((mib[5] = if_nametoindex("en0")) == 0) {         printf("Error: if_nametoindex error/n");         return NULL;     }          if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {         printf("Error: sysctl, take 1/n");         return NULL;     }          if ((buf = malloc(len)) == NULL) {         printf("Could not allocate memory. error!/n");         return NULL;     }          if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {         printf("Error: sysctl, take 2");         return NULL;     }          ifm = (struct if_msghdr *)buf;     sdl = (struct sockaddr_dl *)(ifm + 1);     ptr = (unsigned char *)LLADDR(sdl);     NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",                            *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];     free(buf);          return outstring; } //////////////////////////////////////////////////////////////////////////////// #pragma mark - #pragma mark Public Methods - (NSString *) uniqueDeviceIdentifier{     NSString *macaddress = [[UIDevice currentDevice] macaddress];     NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];       NSString *stringToHash = [NSString stringWithFormat:@"%@%@",macaddress,bundleIdentifier];     NSString *uniqueIdentifier = [stringToHash stringFromMD5];       return uniqueIdentifier; } - (NSString *) uniqueGlobalDeviceIdentifier{     NSString *macaddress = [[UIDevice currentDevice] macaddress];     NSString *uniqueIdentifier = [macaddress stringFromMD5];         return uniqueIdentifier; } @end

NSString + MD5Addition.m:

#import "NSString+MD5Addition.h" #import <CommonCrypto/CommonDigest.h> @implementation NSString(MD5Addition) - (NSString *) stringFromMD5{          if(self == nil || [self length] == 0)         return nil;          const char *value = [self UTF8String];          unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];     CC_MD5(value, strlen(value), outputBuffer);          NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];     for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){         [outputString appendFormat:@"%02x",outputBuffer[count]];     }     return [outputString autorelease]; } @end


Un UUID creado por CFUUIDCreate es único si un usuario desinstala y vuelve a instalar la aplicación: obtendrá una nueva cada vez.

Pero es posible que desee que no sea ​​único, es decir, debe permanecer igual cuando el usuario desinstala y vuelve a instalar la aplicación. Esto requiere un poco de esfuerzo, ya que el identificador por dispositivo más confiable parece ser la dirección MAC. Puede consultar el MAC y usarlo como UUID.

Edición: Uno debe consultar siempre el MAC de la misma interfaz, por supuesto. Supongo que la mejor apuesta es con en0 . El MAC siempre está presente, incluso si la interfaz no tiene IP / está inactiva.

Edición 2: como lo señalaron otros, la solución preferida desde iOS 6 es - [UIDevice identifierForVendor] . En la mayoría de los casos, debería poder usarlo como un reemplazo -[UIDevice uniqueIdentifier] del antiguo -[UIDevice uniqueIdentifier] (pero un UUID que se crea cuando la aplicación se inicia por primera vez es lo que Apple parece querer que use).

Edición 3: Entonces, este punto importante no se pierde en el ruido del comentario: no use el MAC como UUID, cree un hash con el MAC . Ese hash siempre creará el mismo resultado cada vez, incluso entre reinstalaciones y aplicaciones (si el hashing se realiza de la misma manera). De todos modos, en la actualidad (2013) esto ya no es necesario, excepto si necesita un identificador de dispositivo "estable" en iOS <6.0.

Edición 4: en iOS 7, Apple ahora siempre devuelve un valor fijo al consultar el MAC para frustrar específicamente el MAC como base para un esquema de ID . Así que ahora realmente debería usar - [UIDevice identifierForVendor] o crear un UUID por instalación.


Usando el SSKeychain y el código mencionado anteriormente. Aquí está el código para copiar / pegar (agregar el módulo SSKeychain):

+(NSString *) getUUID { //Use the bundle name as the App identifier. No need to get the localized version. NSString *Appname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; //Check if we have UUID already NSString *retrieveuuid = [SSKeychain passwordForService:Appname account:@"user"]; if (retrieveuuid == NULL) { //Create new key for this app/device CFUUIDRef newUniqueId = CFUUIDCreate(kCFAllocatorDefault); retrieveuuid = (__bridge_transfer NSString*)CFUUIDCreateString(kCFAllocatorDefault, newUniqueId); CFRelease(newUniqueId); //Save key to Keychain [SSKeychain setPassword:retrieveuuid forService:Appname account:@"user"]; } return retrieveuuid;

}


iOS 11 ha introducido el framework DeviceCheck. Tiene una solución completa para la identificación única del dispositivo.


mira esto,

podemos usar Keychain en lugar de la clase NSUserDefaults , para almacenar UUID creado por CFUUIDCreate .

de esta manera podríamos evitar la recreación de UUID con la reinstalación, y obtener siempre el mismo UUID para la misma aplicación, incluso el usuario desinstalar y reinstalar nuevamente.

UUID se recreará justo cuando el usuario reinicie el dispositivo.

SFHFKeychainUtils este método con SFHFKeychainUtils y funciona como un encanto.


UIDevice identifierForVendor introducido en iOS 6 funcionaría para sus propósitos.

identifierForVendor es una cadena alfanumérica que identifica de forma única un dispositivo al proveedor de la aplicación. (solo lectura)

@property(nonatomic, readonly, retain) NSUUID *identifierForVendor

El valor de esta propiedad es el mismo para las aplicaciones que provienen del mismo proveedor que se ejecuta en el mismo dispositivo. Se devuelve un valor diferente para las aplicaciones en el mismo dispositivo que provienen de diferentes proveedores, y para las aplicaciones en diferentes dispositivos con respecto al proveedor.

Disponible en iOS 6.0 y versiones posteriores y declarado en UIDevice.h

Para iOS 5 consulte este enlace github


Una alternativa no perfecta, pero una de las mejores y más cercanas a UDID (en Swift con iOS 8.1 y Xcode 6.1):

Generando un UUID aleatorio

let strUUID: String = NSUUID().UUIDString

Y usa la librería KeychainWrapper :

Agregue un valor de cadena a llavero:

let saveSuccessful: Bool = KeychainWrapper.setString("Some String", forKey: "myKey")

Recupere un valor de cadena de llavero:

let retrievedString: String? = KeychainWrapper.stringForKey("myKey")

Eliminar un valor de cadena de llavero:

let removeSuccessful: Bool = KeychainWrapper.removeObjectForKey("myKey")

Esta solución utiliza el llavero, por lo que el registro almacenado en el llavero se conservará, incluso después de desinstalar y reinstalar la aplicación. La única forma de eliminar este registro es restablecer todos los contenidos y configuraciones del dispositivo. Por eso mencioné que esta solución de sustitución no es perfecta, pero sigue siendo una de las mejores soluciones de reemplazo para UDID en iOS 8.1 utilizando Swift.


También tuve algún problema, y ​​la solución es simple:

// Get Bundle Info for Remote Registration (handy if you have more than one app) NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]; NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]; // Get the users Device Model, Display Name, Unique ID, Token & Version Number UIDevice *dev = [UIDevice currentDevice]; NSString *deviceUuid=[dev.identifierForVendor UUIDString]; NSString *deviceName = dev.name;


Una forma de trabajar para obtener UDID:

  1. Inicie un servidor web dentro de la aplicación con dos páginas: una debe devolver el perfil de MobileConfiguration especialmente diseñado y la otra debe recopilar UDID. Más información here , here y here .
  2. Abre la primera página en Mobile Safari desde el interior de la aplicación y le redirige a Settings.app solicitando instalar el perfil de configuración. Después de instalar el perfil, UDID se envía a la segunda página web y puede acceder a él desde dentro de la aplicación. (Settings.app tiene todos los derechos necesarios y diferentes reglas de sandbox).

Un ejemplo usando RoutingHTTPServer :

import UIKit import RoutingHTTPServer @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var bgTask = UIBackgroundTaskInvalid let server = HTTPServer() func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { application.openURL(NSURL(string: "http://localhost:55555")!) return true } func applicationDidEnterBackground(application: UIApplication) { bgTask = application.beginBackgroundTaskWithExpirationHandler() { dispatch_async(dispatch_get_main_queue()) {[unowned self] in application.endBackgroundTask(self.bgTask) self.bgTask = UIBackgroundTaskInvalid } } } } class HTTPServer: RoutingHTTPServer { override init() { super.init() setPort(55555) handleMethod("GET", withPath: "/") { $1.setHeader("Content-Type", value: "application/x-apple-aspen-config") $1.respondWithData(NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("udid", ofType: "mobileconfig")!)!) } handleMethod("POST", withPath: "/") { let raw = NSString(data:$0.body(), encoding:NSISOLatin1StringEncoding) as! String let plistString = raw.substringWithRange(Range(start: raw.rangeOfString("<?xml")!.startIndex,end: raw.rangeOfString("</plist>")!.endIndex)) let plist = NSPropertyListSerialization.propertyListWithData(plistString.dataUsingEncoding(NSISOLatin1StringEncoding)!, options: .allZeros, format: nil, error: nil) as! [String:String] let udid = plist["UDID"]! println(udid) // Here is your UDID! $1.statusCode = 200 $1.respondWithString("see https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/ConfigurationProfileExamples/ConfigurationProfileExamples.html") } start(nil) } }

Aquí están los contenidos de udid.mobileconfig:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>PayloadContent</key> <dict> <key>URL</key> <string>http://localhost:55555</string> <key>DeviceAttributes</key> <array> <string>IMEI</string> <string>UDID</string> <string>PRODUCT</string> <string>VERSION</string> <string>SERIAL</string> </array> </dict> <key>PayloadOrganization</key> <string>udid</string> <key>PayloadDisplayName</key> <string>Get Your UDID</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadUUID</key> <string>9CF421B3-9853-9999-BC8A-982CBD3C907C</string> <key>PayloadIdentifier</key> <string>udid</string> <key>PayloadDescription</key> <string>Install this temporary profile to find and display your current device''s UDID. It is automatically removed from device right after you get your UDID.</string> <key>PayloadType</key> <string>Profile Service</string> </dict> </plist>

La instalación del perfil fallará (no me molesté en implementar una respuesta esperada, ver documentation ), pero la aplicación obtendrá un UDID correcto. Y también debes firmar el mobileconfig .



Apple ha ocultado el UDID de todas las API públicas, comenzando con iOS 7. Cualquier UDID que comience con FFFF es un ID falso. Las aplicaciones "Enviar UDID" que funcionaban anteriormente ya no pueden usarse para recopilar UDID para dispositivos de prueba. (¡suspiro!)

El UDID se muestra cuando un dispositivo está conectado a XCode (en el organizador), y cuando el dispositivo está conectado a iTunes (aunque tiene que hacer clic en ''Número de serie'' para que aparezca el Identificador).

Si necesita obtener el UDID de un dispositivo para agregarlo a un perfil de aprovisionamiento y no puede hacerlo usted mismo en XCode, tendrá que guiarlo a través de los pasos para copiarlo / pegarlo desde iTunes.

¿Hay alguna forma desde (el lanzamiento de iOS 7) para obtener el UDID sin usar iTunes en una PC / Mac?


Podemos usar identifierForVendor para ios7,

-(NSString*)uniqueIDForDevice { NSString* uniqueIdentifier = nil; if( [UIDevice instancesRespondToSelector:@selector(identifierForVendor)] ) { // >=iOS 7 uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; } else { //<=iOS6, Use UDID of Device CFUUIDRef uuid = CFUUIDCreate(NULL); //uniqueIdentifier = ( NSString*)CFUUIDCreateString(NULL, uuid);- for non- ARC uniqueIdentifier = ( NSString*)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));// for ARC CFRelease(uuid); } } return uniqueIdentifier; }

--Nota IMPORTANTE ---

UDID y identifierForVendor son diferentes: ---

1.) On uninstalling and reinstalling the app identifierForVendor will change. 2.) The value of identifierForVendor remains the same for all the apps installed from the same vendor on the device. 3.) The value of identifierForVendor also changes for all the apps if any of the app (from same vendor) is reinstalled.


+ (NSString *) getUniqueUUID { NSError * error; NSString * uuid = [KeychainUtils getPasswordForUsername:kBuyassUser andServiceName:kIdOgBetilngService error:&error]; if (error) { NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]); return nil; } if (!uuid) { DLog(@"No UUID found. Creating a new one."); uuid = [IDManager GetUUID]; uuid = [Util md5String:uuid]; [KeychainUtils storeUsername:USER_NAME andPassword:uuid forServiceName:SERVICE_NAME updateExisting:YES error:&error]; if (error) { NSLog(@"Error getting unique UUID for this device! %@", [error localizedDescription]); return nil; } } return uuid; }