iOS设备唯一标识符 —— OpenUDID

现在这个世纪,手机就是我的半条命,还有可能是多半条。 每人一部手机是标配,有的人可能还有好几个。那么,这么多设备,我们在互联网的世界,如何标明唯一的一个设备呢? 这就引入了“设备唯一标识符”的概念。

在iOS的生态中,有我们所熟知的IDFA,IDFV,UDID,UUID。简直能把人整晕。但是他们含义不同,应用场景不同。为了能在我们的业务中更好的标识一个唯一设备,我们引入OpenUDID类库。

在介绍这个库之前,我们先来看看,上面说的这几个编码到底有哪里不同,以及如何应用。

一、IDFA

IDFA是一串16进制的32位串,全称是Identifier For Advertising。 设计目的是,标识用户设备,用于提供给各个APP之间跟踪广告所用。

例如,你在淘宝里搜索了某个商品之后,你在用浏览器去浏览网页的时候,那个网页的广告就会给你展示相应的那个商品的广告。

IDFA具有以下特性:

  1. IDFA和设备绑定。所有应用在统一设备上获取的都是一样的

  2. iOS10之后,用户可以在设置中关闭限制APP获取

  3. 可以被更改,更改的时机为:

    1. 设置程序 -> 通用 -> 还原 -> 还原位置与隐私

    2. 设置程序-> 通用 -> 关于本机 -> 广告 -> 还原广告标示符

因此,IDFA可以作为一台设备的唯一标识符。但是会有风险被重试,或者被限制获取

二、IDFV

和IDFA非常类似,是一串16进制的32位串。全称是Identifier For Vendor。 但是不同的是,不仅和设备相关,也和APP提供商相关。

IDFV同时和设备,以及APP的提供商相关。一台设备上,同一个APP提供商的IDFV是一样的。

因此,如果将此台设备上,所有这个APP提供商的APP都删除了,则下一次重新安装此提供商APP时,获取的IDFV会变化。

一般可以用于同一个厂家不同APP之间的在本地的数据互通。

三、UDID

是 iOS 设备的一个唯一识别码,每台 iOS 设备都有一个独一无二的编码,全称是Unique Device Identifier。由40位16进制数组成的字符串。 但是在iOS5以后,已经被苹果禁止通过代码获取了。

目前还有三种方式可以看到UDID:

  • 使用iTunes,将手机连接电脑

  • 使用XCode->Device,将手机连接电脑

  • 使用企业级的MDM,制作描述文件,然后搭配网页展示获取UDID。但是只能在Safari中实现。 目前蒲公英是这么做的。可以参考蒲公英的获取UDID的地址:https://www.pgyer.com/udid

具体实现方案,可以参考这里:http://www.skyfox.org/safari-ios-device-udid.html。 因此,苹果为了防止厂家滥用,对于客户端来说,目前已经失去了获取UDID的能力。

四、UUID

UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,是国际标准化组织(ISO)提出了一个概念。 它是一个32位的十六进制序列。其设计目的是,让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。

目前几乎所有系统,windows,Linux,macOS,都已经接入此标准。 UUID是基于当前时间、计数器(counter)和硬件标识(通常为无线网卡的MAC地址)等数据计算生成的。因此,每次重新获取的时候,都不一样,可以在此时此地标识唯一的一台设备。

五、OpenUDID —— 我们使用的识别标识库

UUID目前是比较通用的,在OC中可以通过NSUUID来获取。根据其获取方式,可以知道每次获取都会不同,实际验证也如此。OpenUDID实际也是基于UUID来实现的。

但是我们想要是,一旦我的APP在这台机器上安装上了,无论以后怎么折腾,都获取的是一个。那么,我们应该如何做呢?

此时,OpenUUID给了我们一个解决策略。(虽然这个库已经很多年没更新过了,API基于系统底层,所以相对稳定。) 由于DeviceID对于我们的重要性,我们还是有必要仔细阅读一下此库的源码。

首先用流程图来说明,OpenUDID的核心功能,以及其数据流向:

OpenUDID中所获取的UDID是使用32位UUID进行了40位的补全而来,它的本质就是一个UUID,是可变的。

为了使其不可变,OpenUDID将此值分别存储在了三个地方:

  • 内存变量 — — 在不退出APP时,可以从内存中直接获取之前的ID

  • NSUserDefault — — 在不删除APP时,每次打开APP,可以在NSUserDefault中获取到之前生成的ID

  • UIPasteboard — — 删除了APP后,在同一设备上重新安装APP,依然可以获取到之前已经生成的ID

不可变是我们要的常态,那么我们需要着重关心的是,这个ID什么时候会变化。 由于最终是存在UIPasteboard的不同域中,而iOS不允许用户主动清理剪贴板,所以变化的时机有以下几个:

  • 用户抹掉手机中所有数据,出厂还原为一个新手机

  • 有其他APP,使用API强制清除所有剪贴板(待确认可实施性,但是不排除有这个可能)

  • 由于OpenUDID是开源,不排除极端情况,有其他恶意APP清除OpenUDID使用的剪贴板域

综上,OpenUDID由于聪明地使用了剪贴板做数据持久化以及共享。所以可以保证只要设备上有APP使用了OpenUDID,就可以生成一个唯一识别码,除非以上情况,此识别码将可以一直持续使用,因此,可靠性很高。

对于我们的业务来说,部分功能使用了DeviceID(即我们通过OpenUDID获取给服务器的ID)进行设备识别的模块,例如,即使用户删除APP,再次安装时,也要在登录页面弹出上次他在这台设备上最后一次登录的账号的功能,可以大胆放心的使用此ID作为识别码。

拖地先生,从事互联网技术工作,在这里每周两篇文章,聊聊日常的实践和心得。往期推荐:

说说这个公众号

平均响应1000ms到200ms,PHP和Go那家强?

崩溃率从1%到0.02%,iOS稳定性解决之道

七招优化Android包体减少30%

技术产品职业瓶颈?29份腾讯通道材料教你成长

低头赶路,也别忘了抬头看天

加班能解决交付的期望么?

如果对你有帮助,让大家也看看呗~