在iOS 7中始终获取唯一的设备ID

31

我们的iOS应用程序是为特定用户设计的。因此,我们使用设备唯一标识符来进行用户身份验证。这种方法在iOS 6之前工作得很好,因为我们每次都得到相同的值

NSString *strUniqueIdentifier = [[UIDevice currentDevice] uniqueIdentifier];
在iOS 7中,上述方法返回不同的值,导致用户识别出现问题。iOS 7提供了以下替代方案
NSUUID *oNSUUID = [[UIDevice currentDevice] identifierForVendor];
[strApplicationUUID setString:[oNSUUID UUIDString]];

我们用identifierForVendor替换了uniqueIdentifier,并创建了一个Ad-hoc版本。然后我们在iOS 7和iOS 6设备上安装了该版本。到目前为止,在iOS 7中,我们每次都得到相同的值,但是在iOS 6中,每次卸载并重新安装应用程序时会得到不同的值


你正在测试iOS<6.1.3吗? - Maggie
我的应用程序支持从iOS 5.0到iOS 7.0,现在我正在iOS 7.0上进行测试。 - jaydev
7个回答

30
使用这个小助手方法,在应用程序安装/删除会话之间保留 Keychain 中的标识符。
-(NSString *)getUniqueDeviceIdentifierAsString
{
    NSString *appName=[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];

    NSString *strApplicationUUID = [SSKeychain passwordForService:appName account:@"incoding"];
    if (strApplicationUUID == nil)
    {
        strApplicationUUID  = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
        [SSKeychain setPassword:strApplicationUUID forService:appName account:@"incoding"];
    }

    return strApplicationUUID;
}

SSKeychain库添加到您的项目中,例如通过Cocoapods使用pod 'SSKeychain'


2
当在设备上重置内容和设置时,返回的字符串是不同的。 - Hadi Sharghi

8

UDID被什么替代了?

目前看来,苹果计划用两个不同的标识符替换UDID:供应商ID和广告ID。

供应商ID

在同一开发者的应用程序之间相同的ID。 删除最后一个Team ID的应用程序后会被删除。

广告ID

设备唯一的ID。 可供所有应用程序使用;用于广告 - iAd已从iOS 6及更高版本中的UDID转换。 通过“擦除所有内容和设置”重置。


在大多数情况下,供应商ID将允许拥有多个应用程序的开发者在所有应用程序中将您识别为同一用户。这可以帮助开发者更好地了解他们的受众并提供更好的服务。

广告ID仍将为设备创建唯一标识符,但与UDID不同,可以关闭或重置,就像可以在桌面或笔记本电脑上的浏览器中控制cookie一样。

随着本周早些时候发布iOS7的公告,苹果又迈出了一步,即关闭了另一个独特的标识符 - 应用程序开发者和广告公司可以使用的“MAC地址”,而不是新的广告ID。通过关闭这个漏洞,苹果正在采取积极措施,迫使这些公司只使用用户可以控制的跨应用程序标识符。

尚未确定的是,定向公司是否会继续寻找绕过苹果命令的方法。其他技术,如“设备指纹识别”,已经开发出来,可以在苹果框架之外唯一地识别您的设备。苹果是否会打击这些方法还有待观察。


2
UIDevice类参考中获取identifierForVendor的信息:
当用户从设备中删除该供应商的所有应用程序,然后重新安装其中一个或多个应用程序时,该值会更改。在使用Xcode安装测试版本或使用adhoc分发在设备上安装应用程序时,该值也可能会更改。因此,如果您的应用程序在任何地方存储此属性的值,则应优雅地处理标识符更改的情况。

1
好的,谢谢。但我想要始终获取唯一的ID。否则,是否有其他替代方法可以使唯一ID始终相同,就像设备标识符方法一样。如果可能,请给我建议。或者使用identifierforvander方法是否可行。 - jaydev
不,无法获得始终相同的标识符。文档中都有说明。 - neilco
如果您删除该供应商的所有应用并重新安装一个应用程序,则此值将更改。 - Alex Zavatone

2
iOS7设备上是否安装了同一供应商的其他应用程序?根据文档
“当iOS设备上安装了该应用程序(或来自同一供应商的另一个应用程序)时,此属性中的值保持不变。当用户从设备中删除该供应商的所有应用程序并随后重新安装其中一个或多个应用程序时,该值会更改。在使用Xcode安装测试版本或使用特定分发方式将应用程序安装到设备上时,该值也可能会更改。因此,如果您的应用程序在任何地方存储此属性的值,则应优雅地处理标识符更改的情况。”
你是否通过AppStore提供应用程序?如果没有:
“如果应用程序不是从应用商店安装的(例如,当应用程序仍处于开发阶段时),则基于应用程序的捆绑标识确定供应商。假定捆绑标识以反向DNS格式提供,并且前两个组件用于生成供应商ID。例如,com.example.app1和com.example.app2将显示具有相同供应商ID。”

1
如果设备上没有其他由您签名安装的应用程序,则供应商标识符更改是可以的。此外,如果通过不同的分发方法安装您的应用程序,即通过XCode安装和通过TestFlight或HockeyApp分发时,应用程序可能在安装时具有不同的供应商标识符。

好的,谢谢。但是我想要获取始终唯一的ID。如果没有这样的方法,那么是否有任何替代方案可以使唯一标识符始终相同,就像设备标识符方法一样。如果可能,请给我建议。 - jaydev

0

尝试清除您机器上应用程序的缓存,然后再检查。这可能是您的缓存问题。


0

除了nerowolfe的答案之外,还有一个很棒的钥匙串包装器叫做MCSMKeychainItem,它可以在其他几个方面上进行操作,允许您使用一行代码生成和检索唯一设备ID:

[MCSMApplicationUUIDKeychainItem applicationUUID];

所以基本用法会像这样:

+ (NSString *)deviceId {
  // load unique device ID or generate new one
  return [MCSMApplicationUUIDKeychainItem applicationUUID];
}

它基于Keychain工作,其中存储了一次生成的唯一标识符(如nerowolf建议的)。它是开源的,你可以在这里在github上 下载它。 注意:我不是这个扩展的作者,也不以任何方式认识他/她。

对于那些需要一个真正的设备特定唯一标识且永不改变的人来说,有一个小提示:“如果用户恢复其设备,则UUID将被删除,连同其他钥匙串项目一起”。 - Burak

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