KYOpenUDID是基于OpenUDID的Keychain優(yōu)化版本,安全又持久,老司機(jī)可以直接取(傳送門)。OpenUDID已經(jīng)太久沒有維護(hù),線上環(huán)境實(shí)測證明存在缺陷,多線程并發(fā)使用UIPasteboard相關(guān)接口的確會(huì)導(dǎo)致App卡死現(xiàn)象,在iOS13上導(dǎo)致了58同城、京東、大眾點(diǎn)評(píng)、騰訊視頻等App啟動(dòng)閃退。這是因?yàn)橄到y(tǒng)對于UIPasteboard不但做了線程同步的限制,而且做了進(jìn)程同步限制。在高并發(fā)使用UIPasteboard接口的情況下,很容易使UIPasteboard出現(xiàn)卡住的問題,并且影響整個(gè)系統(tǒng)的App。需要了解細(xì)節(jié)可以看一下唯一標(biāo)示的演化:
設(shè)備ID唯一標(biāo)識(shí),顧名思義就是需要滿足唯一性,用來標(biāo)識(shí)一部設(shè)備,設(shè)備ID可用于統(tǒng)計(jì)用戶新增、留存、活躍等??匆幌翧pple對唯一標(biāo)識(shí)獲取的一路封殺:
== Apple公司于2013年5月1日開始,拒絕采集UDID的App上架App Store
== iOS 5.0 之后uniqueIdentifier方法就被廢棄掉了;
== iOS 7.0 中蘋果又封殺mac地址,把粘貼板的訪問權(quán)限限制在了同一個(gè)開發(fā)者的范圍。
現(xiàn)階段求生之路,官方IDFA與IDFV無法滿足需求,第三方開源SimulateIDFA方案與OpenUDID方案該如何利弊抉擇?
IDFA(identifierForIdentifier)
iOS6系統(tǒng)發(fā)布的時(shí)候,蘋果官方出了一個(gè)IDFA的設(shè)備ID,廣告標(biāo)示符,適用于對外:例如廣告推廣,換量等跨應(yīng)用的用戶追蹤等。
缺陷:通過設(shè)置-> 隱私 -> 廣告 -> 還原廣告標(biāo)示符,可以還原IDFA,iOS7之后也可以通過該頁面的限制廣告跟蹤按鈕,讓IDFA無法獲取。所以IDFA可能出現(xiàn)取不到的情況,而且采集了IDFA后,提交App的時(shí)候,會(huì)問你是否拿了IDFA?是否拿IDFA在App里放廣告?是否用來投放廣告?在審核的時(shí)候需要注意以防蘋果拒絕你的App上架。
IDFV(identifierForVendor)
是給Vendor(應(yīng)用提供商,即開發(fā)者)標(biāo)識(shí)用戶用的,每個(gè)設(shè)備在所屬同一個(gè)Vendor的應(yīng)用里,都有相同的值,適用于對內(nèi):例如分析用戶在應(yīng)用內(nèi)的行為等。準(zhǔn)確點(diǎn)說,是通過BundleID的DNS反轉(zhuǎn)的前兩部分進(jìn)行匹配,如果相同就是同一個(gè)Vender,例如對于com.somecompany.appone,com.somecompany.apptwo
這兩個(gè)BundleID來說,就屬于同一個(gè)Vendor,共享同一個(gè)IDFV的值。雖然IDFV一定可以取到,但也有缺陷:將所有同一個(gè)Vendor下的App全部刪除,重裝后會(huì)重新生成新的IDFV,僅這一條就無法設(shè)備標(biāo)識(shí)的唯一性。
SimulateIDFA
SimulateIDFA原理是收集設(shè)備參數(shù)組合計(jì)算一個(gè)ID值。SimulateIDFA源碼剖析可知前16位計(jì)算的參數(shù)有:系統(tǒng)版本、硬件型號(hào)、運(yùn)營商信息、硬盤容量、核心文件創(chuàng)建、修改時(shí)間(組合計(jì)算一個(gè)16位MD5值后取中間8位后使用%02x占位符填充至16位),后16位計(jì)算的參數(shù)有:系統(tǒng)開機(jī)時(shí)間、國家代碼、系統(tǒng)語言、設(shè)備名稱(組合計(jì)算一個(gè)16位MD5值后取中間8位后使用%02x占位符填充至16位)。SimulateIDFA可以保持極低的重復(fù)率,缺陷:任何易變參數(shù)參數(shù)改變都可導(dǎo)致ID值變化,缺少嚴(yán)謹(jǐn)性唯一性。
OpenUDID
OpenUDID應(yīng)該是目前采用較為廣泛的開源庫,通過源碼剖析原理是使用CFUUIDCreate生成一個(gè)唯一ID,將其存在系統(tǒng)粘貼板(UIPasteboard)上,進(jìn)行存取。
缺陷:iOS7后蘋果把粘貼板的訪問權(quán)限限制在了同一個(gè)開發(fā)者的范圍。線上大量驗(yàn)證OpenUDID對UIPasteboard的操作會(huì)出現(xiàn)一定機(jī)率crash問題,根據(jù)Apple文檔[UIPasteboard pasteboardWithName]的參數(shù)傳遞不會(huì)出現(xiàn)問題,那么問題就出現(xiàn)在實(shí)現(xiàn)代碼,推測為線程不安全:


結(jié)論
Apple本身已經(jīng)堵死了UDID的獲取,IDFA和IDFV都無法滿足,SimulateIDFA缺少嚴(yán)謹(jǐn)穩(wěn)定性,OpenUDID會(huì)造成一定機(jī)率Crash,唯一標(biāo)識(shí)本質(zhì)上只要保證每次取到的ID值一致,那么只需要能能生成一個(gè)唯一值并能穩(wěn)定存取就能達(dá)到目的,Keychain的機(jī)制就可以滿足穩(wěn)定存取,可以采取以下方案組合優(yōu)化:
- IDFA+Keychain (IDFA為空取IDFV)
- IDFV+Keychain
- SimulateIDFA+Keychain
- OpenUDID+Keychain
由于OpenUDID應(yīng)用較為廣泛,我在項(xiàng)目中也采用了,采取的優(yōu)化的方案是基于OpenUDID做存儲(chǔ)優(yōu)化,將其在黏貼版(UIPasteboard)做存儲(chǔ)的方式改為Keychain(如果有多個(gè)App間配置共享),從而有了兼容優(yōu)化版的KYOpenUDID,兼容從OpenUDID直接升級(jí)(已有ID不會(huì)改變),解決了原本的crash問題,安全還持久。Keychain也有同一個(gè)提供商的訪問限制,如果有跨賬號(hào)的多個(gè)App建議將SimulateIDFA也上傳至服務(wù)端作為輔助備選策略。
IDFA,IDFV,Keychain真機(jī)測試結(jié)果數(shù)據(jù)
ipad,iOS 10.2.1 (真機(jī))
第一次
1. idfa--------FBF3BF74-1C10-4AC9-9AD8-F9D0FF0753CF
2. idfv--------64B1DFCF-951D-49F4-B4F4-CC5095316B5C
3. uuid--------F609B6A4-C1D1-4301-89E6-0E16B94EF170
4. keychains---1E0D87A5-0A1F-484E-9C98-8920B2E16F27
第二次
1. idfa--------FBF3BF74-1C10-4AC9-9AD8-F9D0FF0753CF
2. idfv--------64B1DFCF-951D-49F4-B4F4-CC5095316B5C
3. uuid--------BBAC0119-C11A-4C45-AA9F-799570DD028A
4. keychains---1E0D87A5-0A1F-484E-9C98-8920B2E16F27
卸載重裝
1. idfa--------FBF3BF74-1C10-4AC9-9AD8-F9D0FF0753CF
2. idfv--------64B1DFCF-951D-49F4-B4F4-CC5095316B5C
3. uuid--------E73401B0-CA3D-4969-96A0-9C435ED2BED5
4. keychains---1E0D87A5-0A1F-484E-9C98-8920B2E16F27
iPad iOS11.0.3 (真機(jī))
第一次
1. idfa--------DB08FC60-1CE6-4EC5-A20A-D8B909F62642
2. idfv--------B5F266E9-2BCA-46A2-B304-A2BB6C57EF55
3. uuid--------65C3AD4A-F9D5-40D4-BCE4-4E6184D68BC4
4. keychains---644B1FE5-A454-4ACE-AB82-E5B5C1F9127D
第二次
1. idfa--------DB08FC60-1CE6-4EC5-A20A-D8B909F62642
2. idfv--------B5F266E9-2BCA-46A2-B304-A2BB6C57EF55
3. uuid--------5149E9A5-1D65-4989-A6E8-149479F4225D
4. keychains---644B1FE5-A454-4ACE-AB82-E5B5C1F9127D
卸載重裝
1. idfa--------DB08FC60-1CE6-4EC5-A20A-D8B909F62642
2. idfv--------FF76D818-6839-40EC-9C88-58D1CE2A8DC1
3. uuid--------8D892E51-07A1-4F8A-9076-C01A21B1800B
4. keychains---644B1FE5-A454-4ACE-AB82-E5B5C1F9127D