如何使用ObjectiveC将UDID转换为以下格式的UUID(40位到32位)?
[0C50D390-DC8E-436B-8AD0-A36D1B304B18]
[8-4-4-4-12]
兑换???不,您不能将您的 UDID 转换为 UUID。Apple 已从编程方面删除了 UDID。从 2013 年 5 月 1 日起,Apple 开始拒绝访问 UniqueIdentifier 的应用程序。
相反,您可以从代码创建 UUID,该代码将为您提供[8-4-4-4-12]
格式标识符。要生成 UUID,您可以使用CFUUID 类,如下所示:
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
NSString *uuidString = (NSString *)CFUUIDCreateString(NULL,uuidRef);
CFRelease(uuidRef);
NSLog(@"%@",uuidString);
然后,请将其保存uuidString
在UserDefaults或 db 中,因为您无法uuidString
再次生成相同的内容。
如您所知,Apple 在 iOS 5 中已弃用 UDID,但有一种很好的方法可以使用 MD5 算法生成 32 位哈希值。为此需要提供 Wifi-Mac 地址,然后 MD5 将转换为 32 位哈希值。使用此如果您重新安装应用程序,UDID 也不会改变。
注意:Apple 不会在功能 (iOS7) 中接受 Wifi-Mac 地址。一旦 iOS 7 出现图片,您将无法访问 Wifi-Mac 地址。即使您访问您的应用程序,苹果也会简单地拒绝您的应用程序。
您可以有一些替代方案,如下所示,
如果有人在寻找替代方案时偶然发现了这个问题。我在IDManager
课堂上遵循了这种方法,这是来自不同解决方案的集合。KeyChainUtil 是一个从钥匙串中读取的包装器。您还可以将hashed MAC address
用作一种唯一 ID。
/* 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;
}
为了创建我们自己的唯一标识符,我们使用核心基础函数 CFUUIDCreate()。它返回对不透明类型 CFUUIDRef 的引用,我们可以使用 CFUUIDCreateString 函数将其转换为字符串。
将这些调用包装在一个小的 NSString 类别中是一种很好的做法,以便我们可以轻松地重用它们(UUID 在许多情况下会派上用场,例如,如果您需要生成唯一的文件名):
@interface NSString (UUID)
+ (NSString *)uuid;
@end
@implementation NSString (UUID)
+ (NSString *)uuid
{
NSString *uuidString = nil;
CFUUIDRef uuid = CFUUIDCreate(NULL);
if (uuid) {
uuidString = (NSString *)CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
}
return [uuidString autorelease];
}
@end
现在,在我们的代码中,我们在应用程序首次启动时生成一个新的 UUID,并将其存储到用户默认数据库中:
#define UUID_USER_DEFAULTS_KEY @"UUID"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:UUID_USER_DEFAULTS_KEY] == nil) {
[defaults setObject:[NSString uuid] forKey:UUID_USER_DEFAULTS_KEY];
[defaults synchronize];
}
...
希望这将有助于澄清您对 UUID 的疑虑。一切顺利!