在開發中會遇到應用須要記錄設備標示,即便應用卸載後再安裝也可從新識別的狀況,在這寫一種實現方式——讀取設備的UUID(Universally Unique Identifier)並經過KeyChain記錄。html
首先iOS中獲取設備惟一標示符的方法一直隨版本的更新而變化。iOS 2.0版本之後UIDevice提供一個獲取設備惟一標識符的方法uniqueIdentifier,經過該方法咱們能夠獲取設備的序列號,這個也是目前爲止惟一能夠確認惟一的標示符。好景不長,由於該惟一標識符與手機一一對應,蘋果以爲可能會泄露用戶隱私,因此在 iOS 5.0以後該方法就被廢棄掉了;iOS 6.0系統新增了兩個用於替換uniqueIdentifier的接口,分別是:identifierForVendor,advertisingIdentifier,但這兩個接口會在應用從新安裝時改變數值,並非惟一的標示符,因此開發者改成使用WiFi的mac地址來取代;iOS 7中蘋果又封殺mac地址,因此開發者再次改變思路使用KeyChain來保存獲取到的UDID,這樣之後即便APP刪了再裝回來,也能夠從KeyChain中讀取回來。ios
首先保存設備的UUID,可使用類方法+ (id)UUID 是一個類方法,調用該方法能夠得到一個UUID。經過下面的代碼能夠得到一個UUID字符串:git
NSString *uuid = [[NSUUID UUID] UUIDString];
也能夠保存在iOS 6中新增的Vindor標示符 (IDFV-identifierForVendor),獲取這個IDFV的新方法被添加在已有的UIDevice類中。跟advertisingIdentifier同樣,該方法返回的是一個NSUUID對象。github
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
若是用戶卸載了同一個vendor對應的全部程序,而後在從新安裝同一個vendor提供的程序,此時identifierForVendor會被重置,因此這裏要用到KeyChain來保存。
KeyChain(鑰匙串)是使用蘋果設備常常使用的,一般要調試的話,都得安裝證書之類的,這些證書就是保存在KeyChain中,還有咱們平時瀏覽網頁記錄的帳號密碼也都是記錄在KeyChain中。iOS中的KeyChain相比OS X比較簡單,整個系統只有一個KeyChain,每一個程序均可以往KeyChain中記錄數據,並且只能讀取到本身程序記錄在KeyChain中的數據。iOS中Security.framework框架提供了四個主要的方法來操做KeyChain:安全
這四個方法參數比較複雜,一旦傳錯就會致使操做KeyChain失敗,文檔中介紹的比較詳細,你們能夠查查官方文檔。而蘋果提供的KeyChain使用起來略麻煩,因此這裏推薦一個第三方庫SAMKeyChains.SAMKeyChains對蘋果安全框架API進行了簡單封裝,支持對存儲在鑰匙串中密碼、帳戶進行訪問,包括讀取、刪除和設置。SAMKeyChains使用簡單,經過實例代碼即可掌握。app
//保存一個UUID字符串到鑰匙串: CFUUIDRef uuid = CFUUIDCreate(NULL); assert(uuid != NULL); CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid); [SAMKeychain setPassword: [NSString stringWithFormat:@"%@", uuidStr] forService:@"com.yourapp.yourcompany"account:@"user"]; //從鑰匙串讀取UUID: NSString *retrieveuuid = [SAMKeychain passwordForService:@"com.yourapp.yourcompany"account:@"user"]; **注意: setPassword和passwordForSevice方法中的**services 和 accounts 參數應該是一致的。
更多詳細用法說明能夠看SAMKeyChains Documentation框架
基本的實現思路即是這樣,下面是具體的一種具體實現代碼,僅供參考。ide
+ (NSString *)getDeviceId { NSString * currentDeviceUUIDStr = [SAMKeychain passwordForService:@" "account:@"uuid"]; if (currentDeviceUUIDStr == nil || [currentDeviceUUIDStr isEqualToString:@""]) { NSUUID * currentDeviceUUID = [UIDevice currentDevice].identifierForVendor; currentDeviceUUIDStr = currentDeviceUUID.UUIDString; currentDeviceUUIDStr = [currentDeviceUUIDStr stringByReplacingOccurrencesOfString:@"-" withString:@""]; currentDeviceUUIDStr = [currentDeviceUUIDStr lowercaseString]; [SAMKeychain setPassword: currentDeviceUUIDStr forService:@" "account:@"uuid"]; } return currentDeviceUUIDStr; }