我需要一个能够检测iPhone设备的唯一标识字符串,类似于UDID。

19

我希望能够获取 iPhone 设备的唯一标识符字符串,而不是使用已经被苹果淘汰的 UDIDMAC

1. 获取 UDIDMAC 已经被苹果弃用。
2. 我们可以使用UUID,但是在重新安装或删除应用程序后,它会发生变化。

我想要任何设备的唯一值,在重新安装、删除或升级 iOS 版本之后仍然保持不变。


1
你能给我展示一下MAC地址被弃用的文档吗?我之前没有听说过这个。 - James Webster
我认为你唯一的选择是查询MAC地址并对其进行操作。这个问题已经在这里讨论过了,所以我认为这个问题是重复的。而且我不认为MAC地址已经被弃用了,至少我找不到任何文档证明它已经被弃用。 - Krishnabhadra
如果您的iOS目标版本是6.0及以上,则可以使用[[UIDevice currentDevice] identifierForVendor]; - danypata
UDID已被弃用,但这是我第一次听说MAC地址已被弃用。请您分享一下您所阅读的文档,以便我们保持最新状态。还请查看我的回答:http://stackoverflow.com/questions/7128828/what-can-be-used-with-uidevice-currentdevice/16099440#16099440 - Popeye
5个回答

21
您可以使用[[UIDevice currentDevice] identifierForVendor]或其他唯一标识生成器获取唯一标识符,然后应使用KeychainItemWrapper将该值存储在钥匙串中并使用。一旦您在钥匙串中存储了一个值,即使您删除并重新安装应用程序,它也不会被删除。
这是一个有关钥匙串访问的指南- 链接

谢谢你添加钥匙链。我不知道这个。我也会在我的解决方案中实现它。 - badweasel
1
但是如果用户恢复了他/她的手机呢?这时钥匙串也会被删除。 - user2761097

2
正如@danypata所说,可以使用identifierForVendor,具体描述请参见此答案
或者,您也可以尝试使用广告标识符NSUDID,具体描述请参见此处
但是这些标识符可能返回为nil或者随着时间的推移而改变。用户可以选择退出广告跟踪,因此我不建议将其用于自己的目的来跟踪用户。
我想这取决于您最初为什么要跟踪他们的设备。我的态度是,我不需要永远跟踪用户的习惯。我只需要跟踪一般用户趋势和一些DAU信息。因此,我会制作自己的UDID - 在每次应用程序安装时都会更改。在我的下一个版本中,我将使用identifierForVendor,如果它为NIL,我将制作自己的UDID。
这就是我制作自己的UDID的方法:
// this makes a device id like: UUID = 89CD872F-C9AF-4518-9E6C-A01D35AF091C
// except that I'm going to attach some other attributes to it like the OS version, model type, etc.
// the UUID that is stored in user defaults will be like the one above.. but the device id that gets returned
// from this function and sent to [my online system] will have the extra info at the end of the string.
- (void) createUUID {
   // for collecting some data.. let's add some info about the device to the uuid

   NSString *thisDeviceID;
   NSString *systemVersion = [[UIDevice currentDevice]systemVersion];
   NSString *model = [[UIDevice currentDevice]model];
   NSString *retinaTag;
   if (retina) {
       retinaTag = @"Retina";
   }
   else {
       retinaTag = @"";
   }
   NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
   id uuid = [defaults objectForKey:@"uniqueID"];
   if (uuid)
       thisDeviceID = (NSString *)uuid;
   else {
       CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
       thisDeviceID = (__bridge NSString *)cfUuid;
       CFRelease(cfUuid);
       [defaults setObject:thisDeviceID forKey:@"uniqueID"];
   }
   //NSLog(@"UUID = %@", thisDeviceID);

   MYthisDeviceID = [NSString stringWithFormat:@"%@-%@-%@-%@",thisDeviceID,systemVersion,retinaTag,model];

   //NSLog(@"UUID with info = %@", MYthisDeviceID);

然后,发送到我的服务器的单个字符串中包含UDID和设备及操作系统的规格。除非用户完全删除并重新加载应用程序,否则统计数据将显示该设备上的使用情况。为了避免在更新操作系统时获得重复的UDID,可以仅截取UDID部分。

我根本不使用MAC地址,因为我的理解是苹果公司不希望我们使用它。尽管我目前找不到任何文件证明这一点。

iOS7更新:

现在我使用此代码,适用于iOS6和iOS7:

NSString *globalDeviceID;

- (void) createUUID
{
    NSString *thisDeviceID;
    NSString *systemVersion = [[UIDevice currentDevice]systemVersion];
    NSString *model = [[UIDevice currentDevice]model];
    NSString *retinaTag;

    if (retina) {
        retinaTag = @"Retina";
    }
    else {
        retinaTag = @"";
    }

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    id uuid = [defaults objectForKey:@"deviceID"];
    if (uuid)
        thisDeviceID = (NSString *)uuid;
    else {        
        if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) {
            thisDeviceID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
        }
        else
        {
            CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
            thisDeviceID = (__bridge NSString *)cfUuid;
            CFRelease(cfUuid);
        }
        [defaults setObject:thisDeviceID forKey:@"deviceID"];
    }
    NSLog(@"UUID = %@", thisDeviceID);
    globalDeviceID = [NSString stringWithFormat:@"%@-%@-%@-%@",thisDeviceID,systemVersion,retinaTag,model];
    NSLog(@"UUID with info = %@", globalDeviceID);
}

嗨,这段代码在iOS 7上不会崩溃吗?我实现了一个稍微不同的代码形式,它在iOS7上开始崩溃了。 - jeet.chanchawat
我会编辑我的答案,添加我当前在io7中使用的代码版本,它可以很好地运行。 - badweasel
唯一的问题是宣传NSUDID时,苹果公司会在审核期间询问使用情况,因此可能意味着不同的审核或其他任何更好的避免方式...永远不知道... - BootMaker

2
或者简单地使用以下代码并存储到NSUserDefaults中。
[NSProcessInfo processInfo].globallyUniqueString

进程的全局ID。该ID包括主机名、进程ID和时间戳,以确保该ID在网络中是唯一的。


2

尝试

[[UIDevice currentDevice] identifierForVendor];

这是来自iOS 6的内容。


但我不知道我是否可以获取旧版iOS 6的UDID。 - Mahesh

0

我建议看一下OpenUDID

我相信它底层使用MAC地址,所以如果你说访问MAC地址已经被弃用是正确的,那么它可能没有太多用处,但是我认为苹果公司取消访问是不合理的;MAC地址有其他应用,不仅仅是为了UDID而识别设备。


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