前言
有段時間沒再碰到過這個,直到前段時間不斷提及推廣的問題,故總結一下方便使用
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就不會變)
刷機什么的就別指望了,都會變~~~

