iPhone应用的唯一标识符

31

对于一个将图像提交到服务器的iPhone应用程序,我需要以某种方式将同一手机的所有图像联系在一起。每次提交时,我希望发送一些唯一的手机标识符。查看了

[[UIDevice mainDevice] uniqueIdentifier]
[[NSUserDefaults standardDefaults] stringForKey:@"SBFormattedPhoneNumber"]
但在模拟器中出现错误。

是否有一种经过苹果授权的方法可以实现这个功能?


你能访问序列号吗? - Darryl Hein
之前在使用<pre>[[UIDevice mainDevice] uniqueIdentifier]</pre>时出现了错误,但是<pre> [[UIDevice currentDevice] uniqueIdentifier]</pre>似乎可以正常工作。 - Martin Redmond
请参考https://dev59.com/iXVC5IYBdhLWcg3ww0Dr,了解为什么获取SBFormattedPhoneNumber不再起作用。 - Archie
13个回答

41

您遇到了什么错误?[[UIDevice currentDevice] uniqueIdentifier]已编辑以修复API,感谢Martin!)是官方推荐的方法。


4
尝试调用 [UIDevice mainDevice] 出现了未识别的错误,但是尝试使用 [UIDevice currentDevice] 在模拟器中可以正常工作。请注意,这是一条需要翻译的内容,我不会提供解释或其他信息。 - Martin Redmond
9
“[[UIDevice currentDevice] uniqueIdentifier]”已自iOS 5.0起被弃用,不要使用它。我已经阅读过这个GitHub库,该库使用开源库来生成唯一标识符:https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5 - Thomson Comer

18

您还可以使用CFUUID来生成UUID。以下是一些代码:

NSString *uuid = nil;
CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault);
if (theUUID) {
  uuid = NSMakeCollectable(CFUUIDCreateString(kCFAllocatorDefault, theUUID));
  [uuid autorelease];
  CFRelease(theUUID);
}

2
不,每次都不同,所以通常你会在第一次启动时生成它,然后使用NSUserDefaults将其保存到您的首选项中。 - Jason Harris
2
这样做的缺点是,如果应用程序被删除并重新安装,或者设备从备份中恢复,则会丢失保存的UUID,并且无法识别为来自同一设备的内容。 - Jeff Kelley
1
我必须将UUID类型输入为CFUUIDRef,而不是CFUUID。还要记得向您的项目中添加CoreFoundation,并导入<CoreFoundation/CoreFoundation.h>。 - Glenn Barnett

13

目前获得唯一标识符的最简单、最适当的方法是使用苹果明确提供的机制来获取一个 - [[UIDevice currentDevice] uniqueIdentifier]。您不能保证电话号码在设备上是唯一的,或者设备是否具有电话号码。此外,这样做是一种可怕的想法,因为它绝对会侵犯用户的隐私。即使是uniqueidentifier如果您要以任何方式存储它,也应该进行哈希处理。


3
感谢您提醒隐私问题,这方面很多人都选择无视。+1 - jmanning2k
1
正如其他答案所指出的那样,这已经在iOS 5.0中废弃了。 - Nathan Garabedian

8
为了在各个安装之间保留您创建的唯一标识符,您可以使用钥匙串(使用SSKeychain轻松完成):只需按如下方式设置您的UUID即可:
        [SSKeychain setPassword:@"Your UUID" forService:@"com.yourapp.yourcompany" account:@"user"];

然后在需要时随时再次调用:

NSString *retrieveuuid = [SSKeychain passwordForService:@"com.yourapp.yourcompany" account:@"user"];

注意: 服务和账户必须完全匹配。
然后,如果应用程序被删除并重新安装,则UUID将保留重新安装。
如果您想要在多个设备之间共享此UUID,请设置您的应用程序使用iCloud。您可以将UUID存储在NSUserDefaults中,与KeyValueStore同步,然后使用上面的代码将UUID设置到新设备的钥匙串中。
如果我要为上述所有内容键入代码,答案将变得非常冗长,但是这里有很多示例代码可供参考。

7

请不要忘记,在iOS 5中,uniqueIdentifier将被弃用,应该使用CFUUID来替代它。


5
有趣的是,自从iOS 5以后,苹果已经弃用了uniqueIdentifier(正如gN0Me提到的)。以下是相关的TechCrunch文章: http://techcrunch.com/2011/08/19/apple-ios-5-phasing-out-udid/ 苹果建议您不再唯一标识设备,而是标识用户。在大多数情况下,这是很好的建议,尽管仍有一些情况需要一个全局唯一的设备ID。这些情况在广告中非常普遍。因此,我编写了一个极其简单的可插入库,完全复制了现有的行为。
毫不客气地自我推销一下,我会在这里链接它,希望有人会发现它有用。同时,我欢迎所有反馈和批评: http://www.binpress.com/app/myid/591 尽管如此,在您的特定情况下,我建议跳过我库提供的全局唯一ID功能,因为对于您的情况来说有点过度。相反,我会生成一个简单的CFUUID并将其存储在NSUserDefaults中。这个ID将专门针对您的应用程序,但将允许您在数据库中分组所有这个“app安装”所拍摄的照片。
换句话说,通过废弃uniqueIdentifier方法,苹果建议您不是按设备标识,而是按应用程序“安装”进行标识。除非您在特定条件下运行,否则“按应用程序”ID很可能更适合您的产品。

你的解决方案不可用。 - Stas

2

这是一个我也在研究解决的有趣问题。以下是我想要解决的情景。

当你将手机卖给另一个人时会发生什么......那个设备ID将属于其他人,因此即使从iPhone中删除了应用程序,它也可以被重新添加,并且所有数据将重新关联到新用户......这很糟糕。

使用电话号码和设备ID MD5将是一个很好的解决方案。我们提出的另一个解决方案是使用带有一些令牌散列的SQL Lite DB与设备ID进行哈希处理。然后,当应用程序被删除时,DB将被清除,所有数据将被取消关联。我认为这可能太脆弱了。

还有其他的想法吗?

Rob Ellis(PhoneGap / Nitobi)


1
或者手机出现问题并在保修期内更换 - 相同的用户,新手机。在这种情况下,存储在NSUserDefaults中的生成UUID的解决方案将胜出,因为首选项会被同步回来。 - jmanning2k

1

1
只包含链接的答案被认为是不好的做法。请在此总结内容(不要复制/粘贴),以便答案可以独立存在。如果您不这样做,您的答案可能会被删除,特别是如果链接失效。 - Martijn Pieters

0

我用这段代码取得了成功:

- (NSString *)stringUniqueID {
    NSString *  result;
    CFUUIDRef   uuid;
    CFStringRef uuidStr;
    uuid = CFUUIDCreate(NULL);
    assert(uuid != NULL);
    uuidStr = CFUUIDCreateString(NULL, uuid);
    assert(uuidStr != NULL);
    result = [NSString stringWithFormat:@"%@", uuidStr];
    assert(result != nil);
    NSLog(@"UNIQUE ID %@", result);
    CFRelease(uuidStr);
    CFRelease(uuid);
    return result;
}    

0

片段:

NSString *phoneNumber = (NSString *) [[NSUserDefaults standardUserDefaults] objectForKey:@"SBFormattedPhoneNumber"]; // Will return null in simulator!
NSLog(@"Formatted phone number [%@]", phoneNumber);

我最近在OS 2.2.1和OS 3.0上运行了这段代码。

当在设备上运行时,它按预期工作,并返回我的电话号码及完整的国际拨号代码[在我的情况下为1]。

当在模拟器上运行时,返回的值是一个空字符串,因此只能在实际的iPhone设备上使用。

我没有在iPod Touch上测试过它。

...

本周在不同的设备上运行此代码,结果得到了一个空值而非数字。

进一步研究后发现,此代码片段返回的数字是在iTunes中为该设备设置的数字。

如果您在设备激活时没有在iTunes中输入iPhone的号码,或者(如我的情况)如果默认值不是iPhone的号码并且您仍然点击了“确定”,以致于当您的iPhone插入时iTunes不会列出电话号码,则此代码将返回一个空字符串。

[以上是我最近在{{link1:http://www.alexcurylo.com/blog/2008/11/15/snippet-phone-number/]另一篇文章的评论编辑串联]


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