如何生成唯一标识符,可在所有iOS版本中使用?

12

我希望能够获得一个唯一标识符,该标识符应支持所有iOS版本。有人能帮我解决这个问题吗?正如你所知,苹果已经弃用了UDID方法,因此可能使用wifi_mac地址生成唯一标识符。但是苹果将在iOS7版本中删除wifi mac地址。因此,我的要求是生成一个新的唯一代码,它应该在所有iOS版本中都可以工作。谢谢!

注意:一旦用户重新启动设备或重新安装应用程序,请勿更改UDID。


他们废弃这些独特ID的原因是有道理的。创建并存储您自己的UUID(CFUUIDCreate)或使用供应商标识符。 - David Rönnqvist
3个回答

35

我正在更新我的应用程序,该应用程序仅基于唯一标识符操作,支持因此,

1)由于不再可用,我无法使用[UIDevice currentDevice].uniqueIdentifier;

2)我不能使用[UIDevice currentDevice].identifierForVendor.UUIDString,因为它仅适用于iOS 6.0及更高版本,并且无法在较低版本的iOS上使用。

3)MAC地址不是一个选项,因为它在iOS-7中不被允许。

4)OpenUDID在一段时间前已经过时,并且在iOS-6中也存在问题。

5)广告标识符也不适用于iOS-5及以下版本。

最后,这就是我做的事情:

a)将SFHFKeychainUtils添加到项目中

b)生成CFUUID键字符串

 CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault);
    udidString = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));

c) 将其保存到Key Chain Utils,否则每次都会生成一个新的唯一值。

最终代码

+ (NSString *)GetDeviceID {
    NSString *udidString;
   udidString = [self objectForKey:@"deviceID"];
    if(!udidString)
    {
    CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault);
    udidString = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));
    CFRelease(cfuuid);
        [self setObject:udidString forKey:@"deviceID"];
    }
    return udidString;
}

+(void) setObject:(NSString*) object forKey:(NSString*) key
{
    NSString *objectString = object;
    NSError *error = nil;
    [SFHFKeychainUtils storeUsername:key
                         andPassword:objectString
                      forServiceName:@"LIB"
                      updateExisting:YES
                               error:&error];

    if(error)
        NSLog(@"%@", [error localizedDescription]);
}

+(NSString*) objectForKey:(NSString*) key
{
    NSError *error = nil;
    NSString *object = [SFHFKeychainUtils getPasswordForUsername:key
                                                  andServiceName:@"LIB"
                                                           error:&error];
    if(error)
        NSLog(@"%@", [error localizedDescription]);

    return object;
}

enter image description here

更多详情请查看


1
谢谢您。请注意,SFHFKeychainUtils的创建者表示它应该被视为已弃用,应该使用他的STUtils代替。另外,在上面的“GetDeviceID”方法中还应添加CFRelease(cfuuid);以防止内存泄漏。 - ghr
@ghr。是的,他说应该将其视为已弃用,但我在许多应用程序中使用它而没有任何问题。对于第二个问题,感谢您提醒我,我不知道那个。 - Quamber Ali
@NSQuamber.java,在卸载应用程序后,这个生成的ID会改变吗?我有一个要求,要求这个ID必须是唯一的,并且将被发送到服务器。即使用户卸载/重新安装应用程序,我也应该拥有相同的ID。您的解决方案是否可以实现这一点?另外,它对iOS 8.4仍然有效吗? - shamaleyte
2
感觉苹果公司不喜欢开发者.. :-) - Chanchal Raj
@kimimsc,很遗憾,目前的限制仍然存在。没有办法在重新安装后拥有唯一的标识符。如果您找到了解决方法,请分享给我们。我仍然感到绝望:( - shamaleyte
显示剩余3条评论

1
现在设备标识符更改为UUID。您可以使用以下代码获取UUID:
- (NSString *)getUUID
{
    NSString *UUID = [[NSUserDefaults standardUserDefaults] objectForKey:@"uniqueID"];
    if (!UUID) {
        CFUUIDRef theUUID = CFUUIDCreate(NULL);
        CFStringRef string = CFUUIDCreateString(NULL, theUUID);
        CFRelease(theUUID);
        UUID = [(__bridge NSString*)string stringByReplacingOccurrencesOfString:@"-"withString:@""];
        [[NSUserDefaults standardUserDefaults] setValue:UUID forKey:@"uniqueID"];
    }
    return UUID;
}

它适用于所有iOS版本。


是的,一旦重新安装应用程序,UDID就会更改。这个逻辑不能满足我的要求。无论如何,感谢您的逻辑。 - Ganesh

-3

我现在没有访问代码的权限(如果您仍然需要,可以在几个小时后发布),但我所做的是在帮助器类中创建一个静态方法'deviceIdentifier'。

该方法对当前iOS版本进行基本检查,如果低于6.0,则返回UDID,否则返回uniqueIdentifier

如果您需要该代码,请告诉我,我会在能够发布的时候把它发布出来...如果我没记错的话,它只有10-15行左右,但会产生很大的差异,因为您只需调用'[myHelper deviceIdentifier]',无论何时都可以获得设备ID,而不必担心使用哪个iOS版本


非常感谢您的快速回复。正如您所知,苹果已经弃用了UDID方法,因此我实现了使用Mac地址生成唯一标识符的方法。但是,苹果将在iOS7版本中删除wifi Mac地址。因此,我需要生成一个新的唯一代码,它应该适用于包括iOS7在内的所有版本。您能否分享您的逻辑,这将对我非常有帮助。再次感谢您。 - Ganesh
嗨Gahesh - 我刚刚仔细检查了我的代码并记得我完全删除了预先的identifierForVendor代码,只是为了确保符合苹果的指南。我认为他们对于人们在新应用程序中使用UDID甚至只是为了支持旧版本的iiOS也非常严格。 - James Gupta
所以我只是使用identifierForVendor,但我知道这不能满足您的要求,即使在应用程序卸载后它也必须保持不变。 - James Gupta
嗨,詹姆斯,identifierForVendor从iOS 6开始可用。但是使用它,我们可以支持iOS6或更高版本的设备。我的问题是如何支持较低版本。我坚信这方面一定有解决方案。让我们拭目以待 :) - Ganesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接