IOS系統(tǒng)中者蠕,獲取設(shè)備唯一標(biāo)識(shí)的方法有很多:
一.UDID(Unique Device Identifier)
UDID的全稱是Unique Device Identifier筒狠,顧名思義胞皱,它就是蘋果IOS設(shè)備的唯一識(shí)別碼,它由40個(gè)字符的字母和數(shù)字組成捐名。每臺(tái)iOS設(shè)備的UDID是唯一且永遠(yuǎn)不會(huì)改變。但是Unique Device Identifier 最早就被蘋果封殺了,使用會(huì)被拒絕田晚。
iOS 2.0版本以后UIDevice提供一個(gè)獲取設(shè)備唯一標(biāo)識(shí)符的方法uniqueIdentifier,通過(guò)該方法我們可以獲取設(shè)備的序列號(hào)国葬,這個(gè)也是目前為止唯一可以確認(rèn)唯一的標(biāo)示符贤徒。好景不長(zhǎng)芹壕,因?yàn)樵撐ㄒ粯?biāo)識(shí)符與手機(jī)一一對(duì)應(yīng),蘋果覺得可能會(huì)泄露用戶隱私接奈,所以在 iOS 5.0之后該方法就被廢棄掉了踢涌;iOS 6.0系統(tǒng)新增了兩個(gè)用于替換uniqueIdentifier的接口,分別是:identifierForVendor序宦,advertisingIdentifier睁壁,但這兩個(gè)接口會(huì)在應(yīng)用重新安裝時(shí)改變數(shù)值,并不是唯一的標(biāo)示符互捌,所以開發(fā)者改為使用WiFi的mac地址來(lái)取代潘明;iOS 7中蘋果又封殺mac地址。所以說(shuō)秕噪,現(xiàn)在想通過(guò)代碼獲取是不可能的了钳降,如果你想看看你設(shè)備的UDID,可以通過(guò)iTunes來(lái)查看腌巾。
而且我們需要注意的一點(diǎn)是,對(duì)于已越獄了的設(shè)備,UDID并不是唯一的.使用Cydia插件UDIDFaker,可以為每一個(gè)應(yīng)用分配不同的UDID.
所以UDID作為標(biāo)識(shí)唯一設(shè)備的用途已經(jīng)不大了
那么有沒有另外的辦法來(lái)獲取用戶設(shè)備的唯一標(biāo)識(shí)符呢遂填?答案是有的,當(dāng)然這樣的標(biāo)識(shí)符不是蘋果隱藏的UDID了澈蝙,使用OpenUDID開源代碼吓坚,這個(gè)代碼通過(guò)一些特殊的算法,創(chuàng)建了每一個(gè)設(shè)備的唯一標(biāo)識(shí)符碉克,你可以拿過(guò)來(lái)用來(lái)識(shí)別設(shè)備了凌唬。
二.MAC Address
原來(lái)可用,后來(lái)也被蘋果封了漏麦,怕用作盜刷信用卡之用途
三.OPEN UDID
第三方最出名的莫過(guò)于此了客税,但是iOS7這貨也無(wú)法使用了,由于iOS7對(duì)剪貼板(OpenUDID保存到剪貼版中)的限制,導(dǎo)致同一個(gè)設(shè)備上應(yīng)用間撕贞,無(wú)法再共享一個(gè)OpenUDID更耻。
OpenUDID原理:安裝第一個(gè)OpenUDID開發(fā)的游戲App1,生成OpenUDID捏膨,安裝第二款OpenUDID的App2秧均,會(huì)從剪貼板中獲取出之前生成的UDID,App1号涯、App2都是使用的同一個(gè)UDID目胡,但是如果刪除所有OpenUDID的游戲后,重新安裝App1链快,這時(shí)生成的UDID就已經(jīng)重置了誉己,和之前的已然不同,玩家的賬號(hào)信息已丟失域蜗,要被投訴了……
當(dāng)將設(shè)備上所有使用了OpenUDID方案的應(yīng)用程序刪除巨双,且設(shè)備關(guān)機(jī)重啟噪猾,xcode徹底清除并重啟,重裝應(yīng)用程序去獲取OpenUDID筑累,此時(shí)OpenUDID變化袱蜡,與之前不一樣了,
四.UUID(Universally Unique Identifier)
UUID是Universally Unique Identifier的縮寫,中文意思是通用唯一識(shí)別碼.
利用UUID獲取設(shè)備唯一識(shí)別碼有以下三種方式:
1慢宗,利用 NSUserDefaults 存取坪蚁。
這種方法可以保證用戶不刪除軟件情況下的獲取同一個(gè)數(shù)據(jù)。因?yàn)镹SUserDefaults 數(shù)據(jù)時(shí)保存在 沙盒里面的婆廊,會(huì)隨著軟件刪除而被清空迅细。UUID不好的地方就是用戶刪除了你開發(fā)的程序以后,基本上你就不可能獲取之前的數(shù)據(jù)了淘邻。
UUID是基于iOS設(shè)備上面某個(gè)單個(gè)的應(yīng)用程序茵典,只要用戶沒有完全刪除應(yīng)用程序,則這個(gè)UUID在用戶使用該應(yīng)用程序的時(shí)候一直保持不變宾舅。如果用戶刪除了這個(gè)應(yīng)用程序统阿,然后再重新安裝,那么這個(gè)UUID已經(jīng)發(fā)生了改變筹我。
2扶平,通過(guò)調(diào)用[[UIDevice currentDevice]identifierForVendor];方法可以獲取UUID。
此方法是官方6.0系統(tǒng)后推出的蔬蕊,指定唯一標(biāo)示符號(hào)结澄;不同軟件,不同機(jī)器岸夯,運(yùn)行的時(shí)候值都是不一樣的麻献;也就是說(shuō)可以滿足標(biāo)識(shí)唯一性。
但是有一個(gè)問題需要注意猜扮,大部分正版的手機(jī)在軟件卸載了勉吻、然后重新安裝的情況下還是會(huì)保持和原先保存同一個(gè)值。但是對(duì)于有些越獄或者美版的手機(jī) 在卸載后仍然會(huì)重新獲取數(shù)據(jù)旅赢。
3齿桃,Keychain方案
KeyChian 是保存在沙盒之外的存儲(chǔ)數(shù)據(jù),相當(dāng)于Dictionary, 所有應(yīng)用都可以獲取和保存煮盼,因此當(dāng)一個(gè)軟件卸載之后完全不影響里面的數(shù)據(jù)短纵,這樣當(dāng)軟件重新安裝之后,理所當(dāng)然的可以獲取里面的原數(shù)據(jù)僵控。
這里我用的還是別人封裝過(guò)的一些代碼SFHFKeychainUtils(可以在網(wǎng)上任意下載):
//保存數(shù)據(jù)
BOOL s = [SFHFKeychainUtils storeUsername:name andPassword:pswd forServiceName:server updateExisting:NO error:nil];
//獲取密碼
NSString * psw = [SFHFKeychainUtils getPasswordForUsername:name andServiceName:server error:nil];
五.廣告標(biāo)示符(IDFA-identifierForIdentifier)
蘋果推薦的就是使用IDFA香到、IDFV了,官方推薦那必然妥妥的了
idfa: 適用于對(duì)外:例如廣告推廣,換量等跨應(yīng)用的用戶追蹤等
idfv: 適用于對(duì)內(nèi):例如分析用戶在應(yīng)用內(nèi)的行為等
idfa:主要用于廣告养渴,可能會(huì)獲取不到,iOS用戶也可以 設(shè)置|隱私|廣告追蹤 里重置此id的值泛烙,雖然玩家一般不會(huì)重置理卑,但是上述理由已經(jīng)不足以把idfa作為賬號(hào)了
idfv:
顧名思義,是給Vendor標(biāo)識(shí)用戶用的蔽氨,每個(gè)設(shè)備在所屬同一個(gè)Vender的應(yīng)用里藐唠,都有相同的值。其中的Vender是指應(yīng)用提供商鹉究,但準(zhǔn)確點(diǎn)說(shuō)宇立,是通過(guò)BundleID的DNS反轉(zhuǎn)的前兩部分進(jìn)行匹配,如果相同就是同一個(gè)Vender自赔,例如對(duì)于com.somecompany.appone,com.somecompany.apptwo 這兩個(gè)BundleID來(lái)說(shuō)妈嘹,就屬于同一個(gè)Vender,共享同一個(gè)idfv的值绍妨。和idfa不同的是润脸,idfv的值是一定能取到的,所以非常適合于作為內(nèi)部用戶行為分析的主id他去,來(lái)標(biāo)識(shí)用戶毙驯,替代OpenUDID。
這里寫圖片描述
最終方案:
idfv + keychain
六.Vindor標(biāo)示符 (IDFV-identifierForVendor)
Vendor是CFBundleIdentifier(反轉(zhuǎn)DNS格式)的前兩部分灾测。來(lái)自同一個(gè)運(yùn)營(yíng)商的應(yīng)用運(yùn)行在同一個(gè)設(shè)備上爆价,此屬性的值是相同的;不同的運(yùn)營(yíng)商應(yīng)用運(yùn)行在同一個(gè)設(shè)備上值不同媳搪。
經(jīng)測(cè)試铭段,只要設(shè)備上有一個(gè)tencent的app,重新安裝后的identifierForVendor值不變蛾号,如果tencent的app全部刪除稠项,重新安裝后的identifierForVendor值改變。
但是很不幸鲜结,上面所有這些表示設(shè)備唯一號(hào)的標(biāo)識(shí)展运,在IOS7中要么被禁止使用,要么重新安裝程序后兩次獲取的標(biāo)識(shí)符不一樣精刷。
由于IOS系統(tǒng)存儲(chǔ)的數(shù)據(jù)都是在sandBox里面拗胜,一旦刪除App,sandBox也不復(fù)存在怒允。好在有一個(gè)例外埂软,那就是keychain(鑰匙串)。
通常情況下,IOS系統(tǒng)用NSUserDefaults存儲(chǔ)數(shù)據(jù)信息勘畔,但是對(duì)于一些私密信息所灸,比如密碼、證書等等炫七,就需要使用更為安全的keychain了爬立。
keychain里保存的信息不會(huì)因App被刪除而丟失。所以万哪,可以利用這個(gè)keychain這個(gè)特點(diǎn)來(lái)保存設(shè)備唯一標(biāo)識(shí)侠驯。
那么,如何在應(yīng)用里使用使用keyChain呢奕巍,我們需要導(dǎo)入Security.framework 吟策,keychain的操作接口聲明在頭文件SecItem.h里。
直接使用SecItem.h里方法操作keychain的止,需要寫的代碼較為復(fù)雜檩坚,我們可以使用已經(jīng)封裝好了的工具類KeychainItemWrapper來(lái)對(duì)keychain進(jìn)行操作。
KeychainItemWrapper是apple官方例子“GenericKeychain”里一個(gè)訪問keychain常用操作的封裝類诅福,在官網(wǎng)上下載了GenericKeychain項(xiàng)目后效床,
只需要把“KeychainItemWrapper.h”和“KeychainItemWrapper.m”拷貝到我們項(xiàng)目,并導(dǎo)入Security.framework 权谁。KeychainItemWrapper的用法:
/** 初始化一個(gè)保存用戶帳號(hào)的KeychainItemWrapper */
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Account Number"
accessGroup:@"YOUR_APP_ID_HERE.com.yourcompany.AppIdentifier"];
//保存數(shù)據(jù)
[wrapper setObject:@"<帳號(hào)>" forKey:(id)kSecAttrAccount];
[wrapper setObject:@"<帳號(hào)密碼>" forKey:(id)kSecValueData];
//從keychain里取出帳號(hào)密碼
NSString *password = [wrapper objectForKey:(id)kSecValueData];
//清空設(shè)置
[wrapper resetKeychainItem];
其中方法“- (void)setObject:(id)inObject forKey:(id)key;”里參數(shù)“forKey”的值應(yīng)該是Security.framework 里頭文件“SecItem.h”里定義好的key剩檀,用其他字符串做key程序會(huì)出錯(cuò)!