刚刚发现,UIDevice uniqueIdentifier属性在iOS 5中已弃用,在iOS 7及以上版本中不可用。似乎没有可供选择的方法或属性。

我们现有的许多应用程序都紧密依赖于这个属性来唯一地识别特定的设备。今后我们该如何处理这个问题?

2011-2012年的文件建议:

特殊注意事项 不要使用uniqueIdentifier属性。创建特定的唯一标识符 你可以调用CFUUIDCreate函数来创建一个UUID,然后写入 使用NSUserDefaults类将它转换到默认数据库。

但是,如果用户卸载和重新安装应用程序,这个值就不一样了。


当前回答

创建自己的UUID,然后将其存储在Keychain中。因此,即使你的应用程序被卸载,它仍然存在。在许多情况下,即使用户在设备之间迁移(例如完全备份并恢复到另一个设备),它也会持续存在。

实际上,就您所关心的而言,它成为唯一的用户标识符。(甚至比设备标识符更好)。

例子:

我正在定义一个自定义方法来创建一个UUID:

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

然后,你可以在应用的第一次启动时将它存储在KEYCHAIN中。因此,在第一次启动后,我们可以简单地从KEYCHAIN中使用它,不需要重新生成它。使用Keychain存储的主要原因是:当你将UUID设置为Keychain时,即使用户完全卸载了应用程序,然后重新安装它,它也会持续存在。这是存储它的永久方式,这意味着键会一直是唯一的。

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

在应用程序启动包括以下代码:

 // 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
}

下载SSKeychain。m和.h文件从sskeychain和拖动sskeychain。m和.h文件到你的项目,并添加“Security.framework”到你的项目。 要使用UUID,只需使用:

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

其他回答

看看这个,

我们可以使用Keychain来代替NSUserDefaults类,来存储CFUUIDCreate创建的UUID。

这样我们就可以避免重新安装UUID, 即使用户卸载并重新安装,也始终为同一应用程序获得相同的UUID。

用户重置设备时将重新创建UUID。

我用SFHFKeychainUtils尝试了这种方法,它的工作就像一个魅力。

iOS 6中引入的UIDevice identifierForVendor可以满足你的需求。

identifierForVendor是一个字母数字字符串,用于唯一标识应用程序供应商的设备。(只读)

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

对于运行在同一设备上的来自同一供应商的应用程序,此属性的值是相同的。对于同一设备上来自不同供应商的应用程序返回不同的值,对于不同设备上的应用程序返回不同的值,与供应商无关。

在iOS 6.0及更高版本中可用,在UIDevice.h中声明

对于iOS 5,请参考此链接UIDevice-with-UniqueIdentifier-for-iOS-5

如果用户卸载和重新安装应用程序,CFUUIDCreate创建的UUID是唯一的:你每次都会得到一个新的UUID。

但你可能希望它不是唯一的,即它应该保持不变,当用户卸载和重新安装应用程序。这需要一些努力,因为最可靠的每个设备标识符似乎是MAC地址。您可以查询MAC并使用它作为UUID。

编辑:当然,总是需要查询同一接口的MAC。我想最好的选择是en0。MAC一直存在,即使接口没有IP/ down。

编辑2:正如其他人指出的那样,自iOS 6以来首选的解决方案是-[UIDevice identifierForVendor]。在大多数情况下,你应该可以使用它来替换旧的-[UIDevice uniqueIdentifier](但是当应用程序第一次启动时创建的UUID似乎是苹果想要你使用的)。

编辑3:所以这个重点不会在评论噪音中丢失:不要使用MAC作为UUID,使用MAC创建哈希。哈希每次都会创建相同的结果,即使是在重新安装和应用程序之间(如果哈希以相同的方式完成)。不管怎样,现在(2013年)这已经没有必要了,除非你在iOS < 6.0上需要一个“稳定的”设备标识符。

编辑4:在iOS 7中,苹果现在在查询MAC时总是返回一个固定值,以专门阻止MAC作为ID方案的基础。所以你现在应该使用-[UIDevice identifierForVendor]或者创建一个每个安装的UUID。

从iOS 7开始,苹果在所有公共api中都隐藏了UDID。任何以FFFF开头的UDID都是假ID。以前工作的“发送UDID”应用程序不能再用于为测试设备收集UDID。(叹息)

当设备连接到XCode(在管理器中)时,UDID会显示出来,当设备连接到iTunes时(尽管你必须单击“Serial Number”才能显示标识符)。

如果你需要获取设备的UDID来添加到配置配置文件中,并且不能自己在XCode中完成,你将不得不从iTunes中复制/粘贴它。

自iOS 7发布以来,是否有一种方法可以在PC/Mac上不使用iTunes获得UDID ?

根据@moonlight提出的链接,我做了几次测试,这似乎是最好的解决方案。正如@DarkDust所说,该方法将检查始终可用的en0。 有两种选择: uniqueDeviceIdentifier (MAC+CFBundleIdentifier的MD5) 和uniqueGlobalDeviceIdentifier(MAC的MD5),这些总是返回相同的值。 下面是我所做的测试(用真正的设备):

#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 - (AirPlane mode)UDID XXXX7dc3c577446a2bcbd77935bdXXXX - (AirPlane mode)GlobalAppUDID XXXX21f1f19edff198e2a2356bf4XXXX - (Wi-Fi)after removing and reinstalling the app XXXX7dc3c577446a2bcbd77935bdXXXX (Wi-Fi) after removing and installing the app

希望对大家有用。

编辑: 正如其他人指出的那样,这个解决方案在iOS 7中不再有用,因为uniqueIdentifier不再可用,查询MAC地址现在总是返回02:00:00:00:00:00