前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS设备唯一标识符关于UDID代替方案:基于UUID和SSKeychain生成唯一标识符新方法

iOS设备唯一标识符关于UDID代替方案:基于UUID和SSKeychain生成唯一标识符新方法

作者头像
陈满iOS
发布2018-09-10 11:09:32
7.3K1
发布2018-09-10 11:09:32
举报
文章被收录于专栏:陈满iOS陈满iOS

1.传统的UDID与UUID

1.1 通用唯一识别码 UDID(Unique Device Identifier)

是一串由40位16进制数组成的字符串,用以标识唯一的设备,现在想通过代码获取是不可能的了,如果你想看看你设备的UDID,可以通过iTunes来查看。

缺点:

  • 苹果从iOS5开始就移除了通过代码访问UDID的权限,所以码农想知道用户设备的UDID,是不行的。
  • 对于已越狱了的设备,UDID并不是唯一的。使用Cydia插件UDIDFaker,可以为每一个应用分配不同的UDID。 所以UDID作为标识唯一设备的用途已经不大了。

关于获取UDID代码:

  • 尽管iOS5之后已经废掉并被AppStore封杀,但可以欣赏一下:
[[UIDevice currentDevice] uniqueIdentifier];

1.2 设备唯一标识 UUID(Universally Unique IDentifier)

  • 是基于iOS设备上面某个单个的应用程序,只要用户没有完全删除应用程序,则这个UUID在用户使用该应用程序的时候一直保持不变。如果用户删除了这个应用程序,然后再重新安装,那么这个UUID已经发生了改变
  • 同一设备上的不同应用的UUID是互斥的,即能在改设备上标识应用。所以一些人推测,这个UUID应该是根据设备标识和应用标识生成唯一标识,再经过加密而来的(纯推测)。
  • 官方推荐的方法是,每个应用内创建一个UUID来作为唯一标志,并将之存储,但是这个解决方法明显不能接受!

缺点:

  • 你每次创建的UUID都是不一样的,意味着,你卸载后重新安装这个软件,生成的UUID就不一样了,无法达到我们将之作为数据分析的唯一标识符的要求。

关于获取UUID的代码:

[[UIDevice currentDevice] identifierForVendor];

不过,设备唯一标示的问题仍然没有解决:如果你删除应用然后再次安装,这个identifierForVendor的值就变了。

2. 获取设备唯一标识符的推荐新方案

思路:

  • 通过调用CFFUUIDCreate函数来生成机器唯一标识符UUID。但每次调用该函数返回的字符串都不一样,所以第一次调用后需把该字符串存储起来。
  • 尽管CFFUUIDCreate每次获取的UUID会发生变化,最理想的是可以保存在钥匙串keychain里面,并以此作为标识用户设备唯一标识符

2.1 关于获取UUID的官方方案

关于获取UUID,这是官方API的建议方法:

- (NSString *) uniqueString
{
   CFUUIDRef unique = CFUUIDCreate(kCFAllocatorDefault);
   NSString *result = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, unique) autorelease];
   CFRelease(unique);
   return result;
}

2.2 基于SSKeychain的唯一识别码方案

如上获取的UUID,基于Git上的一个第三方库SSKeychain,可以将UUID保存在keychain里面,每次调用先检查钥匙串里面有没有,有则使用,没有则写进去,保证其唯一性,

参考代码:

- (NSString *)getNewUniqueIdNum{
    
    NSString *uuidStr = [SSKeychain passwordForService:@"com.test.app1" account:@"user"];
    if (!uuidStr || [uuidStr isEqualToString:@""])
    {
        CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
        uuidStr = (__bridge NSString *)CFUUIDCreateString(kCFAllocatorDefault ,uuidRef);
        [SSKeychain setPassword:[NSString stringWithFormat:@"%@", uuidStr] forService:@"com.test.app1"account:@"user"];
    }
    return uuidStr;
}

不同于上面调用的字符串转换(__bridge NSString *),另一种写法:

- (NSString *)getNewUniqueIdNum{
    
    NSString *identifierNumber = [SSKeychain passwordForService:@"com.test.app1"account:@"user"];
    CFUUIDRef uuidRef = CFUUIDCreate(NULL);
    assert(uuidRef != NULL);
    CFStringRef uuidStrRef = CFUUIDCreateString(NULL, uuidRef);
    
    if (!identifierNumber){
        
        [SSKeychain setPassword: [NSString stringWithFormat:@"%@", uuidStrRef] forService:@"com.test.app1"account:@"user"];
        identifierNumber = [SSKeychain passwordForService:@"com.test.app1"account:@"user"];
    }
    return identifierNumber;
}

2.3 其它方案

不同于如上SSKeychain,基于一个第三方库SAMKeyChains。SAMKeyChains对苹果安全框架API进行了简单封装,支持对存储在钥匙串中密码、账户进行访问,包括读取、删除和设置。SAMKeyChains使用简单,通过实例代码便可掌握。

基于SAMKeyChains方案的参考代码:

+ (NSString *)getDeviceId
{
    NSString * currentDeviceUUIDStr = [SAMKeychain passwordForService:@" "account:@"uuid"];
    if (currentDeviceUUIDStr == nil || [currentDeviceUUIDStr isEqualToString:@""])
    {
        NSUUID * currentDeviceUUID  =[[UIDevice currentDevice] identifierForVendor];
        currentDeviceUUIDStr = [currentDeviceUUID UUIDString];
        currentDeviceUUIDStr = [currentDeviceUUIDStr stringByReplacingOccurrencesOfString:@"-" withString:@""];
        currentDeviceUUIDStr = [currentDeviceUUIDStr lowercaseString];
        [SAMKeychain setPassword: currentDeviceUUIDStr forService:@" "account:@"uuid"];
    }
    return currentDeviceUUIDStr;
}

3 拓展阅读:官方文档

3.1 涉及的对象

<1>CFUUIDRef

CFUUIDRef

<2>CFStringRef

CFStringRef

3.2 涉及的方法

<1>CFUUIDCreate

CFUUIDCreate

<2>CFUUIDCreateString

CFUUIDCreateString

推荐参考文献

推荐开源项目

其它参考文献

其它开源项目

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.06.20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.传统的UDID与UUID
    • 1.1 通用唯一识别码 UDID(Unique Device Identifier)
      • 1.2 设备唯一标识 UUID(Universally Unique IDentifier)
      • 2. 获取设备唯一标识符的推荐新方案
        • 2.1 关于获取UUID的官方方案
          • 2.2 基于SSKeychain的唯一识别码方案
            • 2.3 其它方案
            • 3 拓展阅读:官方文档
              • 3.1 涉及的对象
                • 3.2 涉及的方法
                • 推荐参考文献
                • 推荐开源项目
                • 其它参考文献
                • 其它开源项目
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档