identificador ForVendor e iOS6

El identifierForVendor ForVendor requiere iOS6, por lo que si mi aplicación actualmente admite iOS4 y, por lo tanto, no puedo utilizarlo, ya que mis actualizaciones siempre deben cumplir con el mínimo previo de mi aplicación. ¿requisito?

Puedes usar esto:

 NSString *udid; if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) udid = [UIDevice currentDevice].identifierForVendor.UUIDString; else udid = [UIDevice currentDevice].uniqueIdentifier; 

con el código del procesador anterior:

 #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrdenetworkingSame) #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrdenetworkingDescending) #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrdenetworkingAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrdenetworkingAscending) #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrdenetworkingDescending) 

No necesita macros de preprocesador para esto, debería verificar si responde, así:

 if ([[UIDevice currentDevice]respondsToSelector:@selector(identifierForVendor)]) { return [UIDevice currentDevice].identifierForVendor.UUIDString; }else{ // return [UIDevice currentDevice]. uniqueIdentifier return [[UIDevice currentDevice] performSelector:@selector(uniqueIdentifier)]; } 

Siempre es diferente UUID incluye marcas de time, por lo que cada vez que llama a esta function, obtendrá una diferente (aleatoria). He seguido este enfoque en la class IDManager , esta es una colección de diferentes soluciones. KeyChainUtil es un contenedor para leer desde llavero. Un llavero similar útil se encuentra en github .

 // IDManager.m /* A replacement for deprecated uniqueIdentifier API. Apple restrict using this from 1st May, 2013. We have to consider, * iOS <6 have not the ASIIdentifer API * When the user upgrade from iOS < 6 to >6 - Check if there is a UUID already stonetworking in keychain. Then use that. - In that case, this UUID is constant for whole device lifetime. Keychain item is not deleted with application deletion. */ #import "IDManager.h" #import "KeychainUtils.h" #import "CommonUtil.h" #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000 #import <AdSupport/AdSupport.h> #endif #include <sys/socket.h> #include <sys/sysctl.h> #include <net/if.h> #include <net/if_dl.h> /* 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" #pragma mark #pragma mark @implementation IDManager + (NSString *) getUniqueID { #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000 if (NSClassFromString(@"ASIdentifierManager")) { NSString * asiID = [[[ASIdentifierManager shanetworkingManager] advertisingIdentifier] UUIDString]; if ([asiID compare:kBuggyASIID] == NSOrdenetworkingSame) { NSLog(@"Error: This device return buggy advertisingIdentifier."); return [IDManager getUniqueUUID]; } else { return asiID; } } else { #endif return [IDManager getUniqueUUID]; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000 } #endif } + (NSString *) getUniqueUUID { NSError * error; NSString * uuid = [KeychainUtils getPasswordForUsername:@"UserName" andServiceName:@"YourServiceName" 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 = [CommonUtil md5String:uuid]; // create md5 hash for security reason [KeychainUtils storeUsername:@"UserName" andPassword:uuid forServiceName:@"YourServiceName" updateExisting:YES error:&error]; if (error) { NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]); return nil; } } return uuid; } + (NSString *) readUUIDFromKeyChain { NSError * error; NSString * uuid = [KeychainUtils getPasswordForUsername:@"UserName" andServiceName:@"YourServiceName" error:&error]; if (error) { NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]); return nil; } return uuid; } /* NSUUID is after iOS 6. So we are using CFUUID for compatibility with iOS 4.3 */ + (NSString *)getUUID { CFUUIDRef theUUID = CFUUIDCreate(NULL); CFStringRef string = CFUUIDCreateString(NULL, theUUID); CFRelease(theUUID); return [(NSString *)string autorelease]; } #pragma mark - MAC address /* THIS WILL NOT WORK IN iOS 7. IT WILL RETURN A CONSTANT MAC ADDRESS ALL THE TIME. SEE - https://developer.apple.com/news/?id=8222013a */ // Return the local MAC address // 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 [CommonUtil md5String:mac]; } @end 

Puede usar el siguiente código

 if (NSClassFromString(@"ASIdentifierManager")) { return [[[ASIdentifierManager shanetworkingManager] advertisingIdentifier] UUIDString]; } else { // return other identifier generated with OpenUDID or some custom method } 

Puede get la documentation de OpenUDID aquí.

Eche un vistazo a NSSelectorFromString y [NSObject performSelector: SEL]. NSSelectorFromString le permite seleccionar un selector por time de ejecución con una cadena. Úselo en combinación con una verificación de la versión del sistema operativo en time de ejecución.