UDID、UUID、IDFA、IDFV的区分记录
前言
有段时间没再碰到过这个,直到前段时间不断提及推广的问题,故总结一下方便使用
UDID
UDID的全称是Unique Device Identifier,顾名思义,它就是苹果IOS设备的唯一识别码,由40个字符的字母和数字组成。移动广告商和游戏网络运营商往往需要通过UDID用来识别玩家用户,并对用户活动进行跟踪。
UDID 在 iOS5.0 的时候已经被抛弃使用了.
调用代码如下
[[UIDevice currentDevice] uniqueIdenfier];
不过不要对它抱有希望,官网API里并没有找到uniqueIdenfier 这个方法~~~
UUID
UUID也被称作 GUID (Globally Unique Identifiers) 或 IID (Interface Identifiers),是一个128-bit的值。
实际上经常说的UUID实际上是有两个类NSUUID和CFUUID,分别来源于两个框架Foundation和CoreFoundation。
CFUUID iOS 2.0+
NSUUID iOS6.0 +
值得注意的是在NSUUID的Overview中有这么一句话
The NSUUID
class is not toll-free bridged with CoreFoundation’s CFUUIDRef
//NSUUID类并不是CoreFoundation框架中CFUUIDRef 的toll-free bridged
OK,那什么是toll-free bridged呢?
所谓的Toll-free bridging是说您可以在某个框架的方法或函数同时使用Core Foundatio和Foundation 框架中的某些类型。很多数据类型支持这一特性,其中包括群体和字符串数据类型。
获取CFUUID
- (NSString *)createCFUUID { // Create universally unique identifier (object) CFUUIDRef uuidObject = CFUUIDCreate(kCFAllocatorDefault); // Get the string representation of CFUUID object. NSString *uuidStr = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuidObject)); CFRelease(uuidObject); return uuidStr; }
至于获取NSUUID的话,可以查看下面的IDFV
IDFA
其实整个AdSupport框架中就只有ASIdentifierManager 的一个类,这个类也很简单的提供了AdvertisingTrackingEnabled和advertisingIdentifier两个属性。
advertisingIdentifie用于获取用户的IDFA值。
Device的identifierForVendor属性,相同的值返回给所有的vendors,这个值或许会被改变,比如说用户擦除设备 - 所以你不应该缓存它。
⚠️注意:在iOS10及以后的版本,如果用户限制广告跟踪,那么返回值都为0.
如果值为nil,那么要等待一会再试。比如:当用户重启设备但没有解锁的时候。
AdvertisingTrackingEnabled用于IDFA是否被限制进行判断
这个属性有这样一句描述
If the value is NO
, use the advertising identifier only for the following purposes: frequency capping, attribution, conversion events, estimating the number of unique users, advertising fraud detection, and debugging.
//如果返回值为NO,那么只把IDFA用于frequency capping, attribution, conversion events, estimating the number of unique users, advertising fraud detection, and debugging.
获取IDFA
#import <AdSupport/AdSupport.h> - (NSString *)getIDFAString { //ios10 之后用户可以限制广告追踪 再次判断用户是否进行了限制 if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) { NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; return adId; } return nil; }
IDFV
由此可见IDFV的值有下面两种情况
相同:自同一设备上运行的同一供应商(vendor)的应用
不同:同一设备上不同供应商(vendor)的应用程序
不同设备上的应用程序(无论供应商(vendor)是否相同)
同时,苹果给出了供应商(vendor)的依据
通常,供应商由App Store提供的数据确定。如果应用程序未从应用程序商店安装(例如企业应用程序和应用程序仍在开发中),则根据应用程序的bundle ID计算供应商标识符。bundle ID 被认为是反向DNS格式。
-
-
在iOS 6上,bundle ID的前两个部分用于生成供应商ID。如果捆绑包ID仅具有单个组件,则使用整个bundle ID。
-
在IOS 7上,除最后一个组件之外的所有组件都用于生成供应商ID。如果软件包ID仅包含单个组件,则使用整个bundle ID。
-
然后给了个🌰
Bundle ID |
iOS 6.x |
iOS 7.x |
---|---|---|
com.example.app1 |
com.example.app1 |
com.example.app1 |
com.example.app2 |
com.example.app2 |
com.example.app2 |
com.example.app.app1 |
com.example.app.app1 |
com.example.app.app1 |
com.example.app.app2 |
com.example.app.app2 |
com.example.app.app2 |
example |
example |
example |
和IDFA类似,同样存在为nil的情况,比如:当用户重启设备但没有解锁的时候。
IDFV改变的情况
不变:此应用程序(或来自同一供应商的另一个应用程序)安装在iOS设备上时
改变:用户删除所有供应商(vender)程序后,又一次安装时这个值会变
使用Xcode安装测试版本时或在使用ad-hoc分发的设备上安装应用程序时,该值也会发生变化。(其实还是供应商app存不存在的问题)
即使你存有keyChain,删除所有此供应商(vender)的app,重新安装也是会变的
获取IDFV
- (NSString *)getIDFVString { NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; return idfv; }
总结
本身苹果对用户隐私的重视使得我们并不能完全的定位手机,所以当你搜索的时候大都是推荐使用UUID+keyChain的方式。而你细看他们代码的话其实大都是保存的CFUUID。
这么说来获取NSUUID的值实际上就是获取了IDFV。
下面来做一下区分
CFUUID:经常会变,每次获取都会发生改变
IDFA:所有供应商(vendor)的IDFA都一样(感觉上是那种所有app同生共死的感觉)
IDFV:同一个供应商(vendor)只要至少有一个还在手机中就不会改变(简单说就是要灭灭一家,有幸存者这个IDFV就不会变)
刷机什么的就别指望了,都会变~~~