技 術 文 章 / 超 人
2020.11.12? 更新IDFA獲取方式,iOS14獲取IDFA策略改變
學無止境,人無完人,在不斷學習中成長。如果文章中有錯誤或者紕漏,感謝讀者提出,本人確認后將會有小禮品送上???
唯一標識優先級排序:
UUID(IOS6已被禁用) --->Mac地址(IOS7已被禁用) --->IDFA(優點:不同應用獲取的IDFA相同。缺點:系統重置、(設置程序 -> 隱私 -> 廣告 -> 還原廣告標識)會造成IDFA改變,用戶關閉IDFA標識的獲取,將獲取不到。應用獲取IDFA不符合蘋果要求,應用將會被拒) --->(CFUUID或NSUUID) + SSKeychain(優點:同一個開發者賬號創建的所有應用獲取的設備碼都一樣。系統升級、應用被刪除設備碼不變。缺點:不同開發者創建的應用獲取的值不同,系統重置且不備份會重置該值。) --->Vindor標示符--->OpenUDID(每個應用獲取的設備碼不一樣。同一應用每次獲取都一樣.應用被刪除后設備碼改變)
目前國內兩大移動統計平臺友盟和TalkingData 的SDK分別用的是
友盟:Openudid+IDFA
TalkingData:Keychain+IDFA
目前我自己使用的是(CFUUID或NSUUID) + SSKeychain的方法 + IDFA
1.CFUUID
從iOS2.0開始,CFUUID就已經出現了。它是CoreFoundatio包的一部分,因此API屬于C語言風格。CFUUIDCreate方法用來創建CFUUIDRef,并且可以獲得一個相應的NSString,如下代碼:
獲得的這個CFUUID值系統并沒有存儲。每次調用CFUUIDCreate,系統都會返回一個新的唯一標示符。如果你希望存儲這個標示符,那么需要自己將其存儲到NSUserDefaults, Keychain, Pasteboard或其它地方。
2.NSUUID
NSUUID在iOS 6中才出現,這跟CFUUID幾乎完全一樣,只不過它是Objective-C接口。+ (id)UUID 是一個類方法,調用該方法可以獲得一個UUID。通過下面的代碼可以獲得一個UUID字符串:
跟CFUUID一樣,這個值系統也不會存儲,每次調用的時候都會獲得一個新的唯一標示符。如果要存儲的話,你需要自己存儲(例如SSKeyChain)。在我讀取NSUUID時,注意到獲取到的這個值跟CFUUID的值幾乎不可能一樣,但也有170億分之1的可能一樣。
3.廣告標示符(IDFA-identifierForIdentifier)
IDFA是iOS6.0及以后提供的新方法,advertisingidentifier是新框架AdSupport.framework的一部分。ASIdentifierManager單例提供了一個方法advertisingIdentifier,通過調用該方法會返回一個上面提到的NSUUID實例。
跟CFUUID和NSUUID不一樣,廣告標示符是由系統存儲著的。不過即使這是由系統存儲的,但是有幾種情況下,會重新生成廣告標示符。如果用戶完全重置系統(設置程序 -> 通用 -> 還原 -> 還原位置與隱私) ,這個廣告標示符會重新生成。另外如果用戶明確的還原廣告(設置程序-> 通用 -> 關于本機 -> 廣告 -> 還原廣告標示符) ,那么廣告標示符也會重新生成。關于廣告標示符的還原,有一點需要注意:如果程序在后臺運行,此時用戶“還原廣告標示符”,然后再回到程序中,此時獲取廣告標示符并不會立即獲得還原后的標示符。必須要終止程序,然后再重新啟動程序,才能獲得還原后的廣告標示符。之所以會這樣,我猜測是由于ASIdentifierManager是一個單例。
針對廣告標示符用戶有一個可控的開關“限制廣告跟蹤”。Nick Arnott的文章中已經指出了。將這個開關打開,實際上什么也沒有做,不過這是希望限制你訪問廣告標示符。這個開關是一個簡單的boolean標志,當將廣告標示符發到任意的服務器端時,你最好判斷一下這個值,然后再做決定。
4.Vindor標示符 (IDFV-identifierForVendor)
這種叫法也是在iOS 6中新增的,不過獲取這個IDFV的新方法被添加在已有的UIDevice類中。跟advertisingIdentifier一樣,該方法返回的是一個NSUUID對象。Vindor顧名思義,是給Vendor標識用戶用的,每個設備在所屬同一個Vender的應用里,都有相同的值。其中的Vender是指應用提供商,但準確點說,是通過BundleID的反轉的前兩部分進行匹配,如果相同就是同一個Vender,例如對于com.demo.app1, com.demo.app2 這兩個BundleID來說,就屬于同一個Vender,共享同一個idfv的值。和idfa不同的是,idfv的值是一定能取到的,所以非常適合于作為內部用戶行為分析的主id,來標識用戶,替代OpenUDID。
iOS14之前獲取IDFA
但現在獲取IDFA必須在info.plist里申請獲取權限,在判斷權限狀態,才能獲取IDFA
注意:該權限和引入庫,只有xcode12及以上版本才有!!!
1.info.plist里申請權限?NSUserTrackingUsageDescription
2.引入相關庫
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/AdSupport.h>
3.檢查權限狀態并獲取值
蘋果官方的文檔中對identifierForVendor有如下這樣的一段描述 :
The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor.
a.如果相同的一個程序里面-相同的vindor-相同的設備,那么獲取到的這個屬性值就相同。
b.如果相同的程序-相同的設備-不同的vindor,或者是相同的程序-不同的設備-無論是否相同的vindor,那么獲取到的這個屬性值就不同。
注意:如果用戶將屬于此Vender的所有App卸載,則idfv的值會被重置,即再重裝此Vender的App,idfv的值和之前不同。
5.UDID
6.OpenUDID
Openudid是一個github上一個開源的項目:地址
原理是利用iOS系統中的UIPasteboard剪貼板類,它用app-special pastboards來存儲一160位的隨機字符串,存取的方式類似字典的key-value。app-special pastboards可持久存儲字符串,即使開關機、卸載應用,并能在app之間共享。Openudid的第一次訪問的時候用key去檢查剪貼板內是否存在對應的value(隨機數),如果不存在就生成一個并存儲在Pasteboard中,第二次訪問的時候就可以直接取到而不去生成新的隨機數。但是iOS7之后,蘋果封堵了剪貼板通信的漏洞,iOS之前是所有的應用都可以共享同一個剪貼板存儲內容,現在只有在同一CFBundleIdentifier標識下的App才能共享內容,如com.demo.a和com.demo.b,它們的com.mycompany部分是一樣的,就能共享(請用真機測試,模擬器會有偏差)。
NSString *openUDID = [OpenUDID value];
7.Mac地址
MAC地址就如同我們身份證上的身份證號碼,具有全球唯一性。這樣就可以非常好的標識設備唯一性,類似與蘋果設備的UDID號,通常的用途有:1)用于一些統計與分析目的,利用用戶的操作習慣和數據更好的規劃產品;2)作為用戶ID來唯一識別用戶,可以用游客身份使用app又能在服務器端保存相應的信息,省去用戶名、密碼等注冊過程。UDID被禁以后大家開始在iOS6中使用 MAC 地址(Medium/Media Access Control) ,后來又被Apple官方在iOS7中禁止掉了。從iOS7及更高版本往后,如果你向ios設備請求獲取mac地址,系統將返回一個固定值“02:00:00:00:00:00”
Mac地址生成設備的唯一標識主要分三種:
? ? ? 1、直接使用“MAC Address”
? ? ? 2、使用“MD5(MAC Address)”
? ? ? 3、使用“MD5(Mac Address+bundle_id)”獲得“機器+應用”的唯一標識(bundle_id 是應用的唯一標識)
8.網上有說使用 ?推送token+bundle_id
1、應用中增加推送用來獲取token
2、獲取應用bundle_id
3、根據token+bundle_id進行散列運算
apple push token保證設備唯一,但必須有網絡情況下才能工作,該方法不依賴于設備本身,但依賴于apple push,而蘋果push有時候會抽風的。
9.SSkeyChain
keychain中文翻譯為鑰匙串,是蘋果用來存儲密碼和證書的一塊加密存儲區域,目的是為了幫助用戶安全存儲應用或者瀏覽器的密碼,省去了很多輸入密碼和記密碼的麻煩。keychain不是存儲在手機的沙盒內,而是手機的某個公共區域,手機重啟和應用卸載,都不會對這片存儲區域造成影響,因為是加密存儲不存在被其他應用修改的問題,所以就有人拿keychain來存儲唯一標識。需要Security.framework支持。
再Max OS上訪問keychian需要提供用戶的登錄密碼,而在iOS上用戶原則上只能訪問本應用存儲的keychain,除非是同一個provisioning 證書的兩個應用,比如美團的貓眼就能讀取美團app中的keychian,用戶第一次打開貓眼app就會彈出提示,用戶可以讀取美團的賬號和密碼免登錄進入貓眼。keychain是根據provision 證書來鑒定權限,所以app的版本需要使用同一個,否則版本之間會失效。用戶恢復出廠設置,機器上的keychain會被清除,但如果事先對手機進行了備份,keychain存儲的內容依然有效。順便提一句keychain在越獄的機器上是可以被導出的,所以存儲敏感信息前請加密。
關于使用
(CFUUID或NSUUID) + SSKeychain后,開發者賬號發生改變,蘋果給出的相關說明