美文网首页
iOS | 创建设备的唯一标识 抗疫勇士需要被刻骨铭记,每台设备

iOS | 创建设备的唯一标识 抗疫勇士需要被刻骨铭记,每台设备

作者: BinaryBang | 来源:发表于2020-04-04 23:31 被阅读0次

    1 前言

    今天是清明节,全球都面临着新冠病毒的威胁.有很多很多的勇士为了抗击疫情,献出了自己宝贵的生命.没有岁月静好,我们都需要全力以赴地前行.
    作为程序员,我能做得就是认真写好每一个程序,我不懂如何消灭疫情,但是我需要消灭程序里的bug.

    在很多情况下,我们希望能够有一个设备标识符来标识一个设备.确保不同设备的标识符是不同的,而同一台设备的不同应用之间,又能够获得到相同的标识符.

    我们很容易想到iOS的UDID本身就具有这个功能,但是在iOS5之后,苹果出于信息安全方面的考虑,废除了程序中获取UDID的方式.

    所以,我们需要用另一种方式来给设备颁发身份证.
    我们逐个分析下,看看哪些是可行的.

    1 UUID+KeyChain

    什么是UUID?
    UUID是Universally Unique Identifier通用唯一识别码,是一种让分布式系统中的所有元素,都能有唯一的辨识信息的机制.
    我们可以用UUID来作为设备的唯一标识.

    iOS中有两种简单的方式获取UUID:

    //方式一:
    CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault);
    NSString *cfuuidString = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));
    
    //方式二:
    NSString *uuid = [[NSUUID UUID] UUIDString];
    

    生成UUID的方式很简单,但是每次生成,都会得到不同的UUID.
    我们需要在每次获取时,首先在一个全局位置查询是否存在,如果存在就直接返回,不存在才生成,并存储到这个全局位置.
    所以,这个全局的位置,是这种方案的关键.

    设么是KeyChain?
    KeyChain是iOS设备中的一个加密数据库,用来存储少量的用户私密信息.
    并且通过设置程序的访问组,可以实现多个App之间共享数据.
    无疑KeyChain就是这个最理想的的全局位置.

    所以UUID+KeyChain生成设备唯一标识符的总体思路是:

    • 1 为需要共享信息的App之间设置一个共享访问组.
    • 2 App获取唯一标识符时,首先从KeyChain中获取,如果没有,则新建并保存;如果有,则直接返回.

    该方案,是创建设备唯一标识符的最佳实践,具体实现,请单独参考这篇文章:iOS | Uuid+KeyChain 我的设备性能不是最牛逼的,但他是全球唯一的

    2 广告标识符Identifier For Advertising(IDFA)

    IDFA是一个跟device相关的唯一标识符,主要用来广告相关的业务,每台设备的IDFA是唯一的(模拟器获取的广告标识符都是00000000-0000-0000-0000-000000000000,必须在真机上才能获取到).

    IDFA和应用无关,本设备上的任何App获取到IDFA的内容都是一致的.
    获取的方式也很简单:

    #import <AdSupport/AdSupport.h>
    NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
    

    IDFA在以下情况下会重新生成:

    • 重置系统,设置->通用->还原->还原位置与隐私
    • 还原广告标识符,设置->通用->关于本机->广告->还原广告标识符

    如果认可这两种条件下的标识符重置,其实获取IDFA是用来标识设备的最简单有效的方法.

    3 Push token

    如果应用中使用了推送功能,我们就会得到一个deviceToken.

    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
    

    而这个deviceToken,就是一个设备唯一的值.也可以用来作为设备标识.

    但是这个方案有两大缺点:
    1,必须在有外网的情况下才能获取到;
    2,DeviceToken是保证唯一的,但是不确定会不会发生改变.从唯一值A,变为唯一值B.

    4 设备唯一标识符Unique Device Identifier(UDID)

    UDID是苹果设备的唯一识别码,在iOS 5以前可以直接用代码获取,获取方式也很简单:

    NSString *udid = [[UIDevice currentDevice] uniqueIdentifier];
    

    但是在iOS5以及之后,苹果处于保护用户隐私等原因,不再提供该方式让开发者获取设备的UDID

    5 供应商标识符IdentifierForVendor(IDFV)

    供应商标识符,是用来标识应用供应商的.每个供应商的所有应用,都有相同的值。

    如何判断两个应用是否属于同一个供应商?
    通过BundleID的反转的前两部分进行匹配,如果相同就是同一个供应商.例如对于com.taobao.app1, com.taobao.app2 这两个BundleID来说,就属于同一个供应商,共享同一个IDFV的值。

    它是iOS 6中新增的,跟advertisingIdentifier一样,该方法返回的是一个 NSUUID对象,可以获得一个UUID。获取方式也很简单

    NSString *strIDFV = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    

    但是如果用户将属于此供应商的所有App卸载,则IDFV的值会被重置,即再重装此供应商的App,IDFV的值和之前不同。

    所以IDFV不适合用来作为设备的唯一标识符.

    6 Mac地址

    什么是Mac地址?
    每一个网卡都有一个唯一标识符,叫做Mac地址.一部iPhone上有多个网卡,Wifi的网卡,流量的网卡等,所以会有多个Mac地址.但是每个Mac肯定是唯一的.

    但是iOS7之后,获取Mac地址苹果也限制了开发者获取Mac地址,所以这个方案也不行了.

    总结

    经过上述分析,我们发现:

    • Mac地址,UDID的方式 已经不被苹果支持,无法实现.
    • IDFV,具有很大的局限性,也不提倡.
    • PushToken的方案,客观来说,有点离谱,非常不提倡.
    • IDFA,如果能够接受还原时标识符的重置,其实是最简单的方案.
    • Uuid+KeyChain,这种方式才是最佳实践,具体的实现方案,请参考:iOS | Uuid+KeyChain 让你的设备全球唯一

    参考资料

    相关文章

      网友评论

          本文标题:iOS | 创建设备的唯一标识 抗疫勇士需要被刻骨铭记,每台设备

          本文链接:https://www.haomeiwen.com/subject/elyephtx.html