獲取UUID并保存到鑰匙串

前言:

1 .為了統(tǒng)計和檢測應用的使用數(shù)據(jù)扁掸,幾乎每家公司都有獲取唯一標識的業(yè)務需求蝴韭,在iOS5以前獲取唯一標識,可以獲取到系統(tǒng)提供的方法UDID(Unique Device Identifier)刀脏,后來被出于用戶隱私的考慮被Apple官方禁止掉了。于是宝踪,大家開始在iOS6中使用 MAC 地址(Medium/Media Access Control) ,后來又被Apple官方在iOS7中禁止掉了祟印。蘋果及其國外的IT公司都會比較注重用戶隱私肴沫,所以今后一但有比較靠譜的獲取唯一標示的方法放出,蘋果肯定會封堵蕴忆。

2.**  ** 在非越獄的手機上獲取某個硬件信息生成唯一標識颤芬,第一只能找到蘋果的漏洞,第二就是調用一些私有接口套鹅,顯然這兩條路都比較艱難站蝠,并不可持續(xù)發(fā)展,所以網上大部分的唯一標識都是從操作系統(tǒng)層面獲取的卓鹿,在重置手機系統(tǒng)的時候都會被清除菱魔,在系統(tǒng)升級、卸載重裝吟孙、備份恢復都可以保留澜倦,現(xiàn)在本人尚未發(fā)現(xiàn)可以使用嚴格意義上的唯一標識聚蝶。接下來我想跟大家探討的是如何通過“合法”的手段來盡量拿到不會輕易發(fā)生變化的“唯一標識”。

3.**  **在2013年3月21日蘋果已經通知開發(fā)者藻治,從2013年5月1日起碘勉,訪問UIDID的應用將不再能通過審核,替代的方案是開發(fā)者應該使用“在iOS?6中介紹的Vendor或Advertising標示符”桩卵。

4.MAC地址不能再用來設別設備

**  **還有一個生成iOS設備唯一標示符的方法是使用iOS設備的Media Access Control(MAC)地址验靡。一個MAC地址是一個唯一的號碼,它是物理網絡層級方面分配給網絡適配器的雏节。這個地址蘋果還有其他的名字胜嗓,比如說是硬件地址(Hardware Address)或是Wifi地址,都是指同樣的東西钩乍。

有很多工程和框架都使用這個方法來生成唯一的設備ID辞州。比如說ODIN。然而件蚕,蘋果并不希望有人通過MAC地址來分辨用戶孙技,所以如果你在iOS7系統(tǒng)上查詢MAC地址产禾,它現(xiàn)在只會返回02:00:00:00:00:00排作。

5 **  ** 講真蘋果這傲嬌的小脾氣什么時候能能改改,不過這樣 對于用戶隱私的保護,確實起到很大作用,而且蘋果也沒有把路堵死,現(xiàn)在蘋果明確的表明你應該使用-[UIDevice identifierForVendor]或是-[ASIdentifierManager advertisingIdentifier]來作為你框架和應用的唯一標示符。坦白的來說亚情,應對這些變化也不是那么的難妄痪,見以下代碼片段:

NSString*identifierForVendor=[[UIDevice currentDevice].identifierForVendor UUIDString];NSString*identifierForAdvertising=[[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];

但是這樣用法有個缺點,就是程序每次被刪除以后,獲取到的都是新的uuid,并不能實現(xiàn)每個手機的唯一性.

所以下面要講的就是這個問題的解決辦法.

**  **對于這個問題有一個可行的辦法,就是把獲取到的uuid保存在鑰匙串里面,這樣即使程序刪除重裝,獲取到的uuid一直是同一個,實現(xiàn)了手機的唯一標識的作用.

保存鑰匙串 我們需要用到keychain,除此之外,Code Signing Entitlements的創(chuàng)建方法也不夠嚴謹楞件。下面教大家一種方法,簡單快速.

1.新建一個工程衫生,看一下自己的Bundle Id.這個Bundle Id 要和你用真機測試時的證書上面的Bundle Id相匹配。

注意這個Bundle identifier

2.Target - Capabilities - Keychain Sharing - ON

注意圓圈里面的保持一致

這步主要目的是打開Keychain Sharing,將它由灰色狀態(tài)的OFF改為藍色狀態(tài)的ON土浸。

會自動生成這個

左側的目錄會自動生成Entitlements文件罪针,不需要自己創(chuàng)建了。

也就是說黄伊,Bundle Identifier泪酱、Keychain Sharing的Keychain Groups、Entitlements文件的Keychain Access Groups的第一個元素还最,它們要保持上圖所示的一致性墓阀。

設置好了以后可以運行下程序,沒問題可以進行下一步拓轻。

.傳說中的uuid類和keychain類來啦

既然蘋果的keychain方法會崩潰而且有些復雜斯撮,我們只保存一個uuid的話可以用下面的簡單方法:

KeyChainStore.h#import@interfaceKeyChainStore:NSObject+(void)save:(NSString*)service data:(id)data;+(id)load:(NSString*)service;+(void)deleteKeyData:(NSString*)service;@end

KeyChainStore.m////? KeyChainStore.m//? getUUID////? Created by ckl@pmm on 16/9/18.//? Copyright ? 2016年 CKLPronetway. All rights reserved.//#import"KeyChainStore.h"@implementationKeyChainStore+(NSMutableDictionary*)getKeychainQuery:(NSString*)service{return[NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassGenericPassword,(id)kSecClass,service,(id)kSecAttrService,service,(id)kSecAttrAccount,(id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,nil];}+(void)save:(NSString*)service data:(id)data{//Get search dictionaryNSMutableDictionary*keychainQuery=[selfgetKeychainQuery:service];//Delete old item before add new itemSecItemDelete((CFDictionaryRef)keychainQuery);//Add new object to search dictionary(Attention:the data format)[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data]forKey:(id)kSecValueData];//Add item to keychain with the search dictionarySecItemAdd((CFDictionaryRef)keychainQuery,NULL);}+(id)load:(NSString*)service{id ret=nil;NSMutableDictionary*keychainQuery=[selfgetKeychainQuery:service];//Configure the search setting//Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue[keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];[keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];CFDataRef keyData=NULL;if(SecItemCopyMatching((CFDictionaryRef)keychainQuery,(CFTypeRef*)&keyData)==noErr){@try{ret=[NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData*)keyData];}@catch(NSException*e){NSLog(@"Unarchive of %@ failed: %@",service,e);}@finally{}}if(keyData)CFRelease(keyData);returnret;}+(void)deleteKeyData:(NSString*)service{NSMutableDictionary*keychainQuery=[selfgetKeychainQuery:service];SecItemDelete((CFDictionaryRef)keychainQuery);}@end

getUUID.h#import@interfacegetUUID:NSObject+(NSString*)getUUID;@end

getUUID.m////? getUUID.m//? getUUID////? Created by ckl@pmm on 16/9/18.//? Copyright ? 2016年 CKLPronetway. All rights reserved.//#import"getUUID.h"#import"KeyChainStore.h"#defineKEY_USERNAME_PASSWORD @"com.company.app.usernamepassword"#defineKEY_USERNAME @"com.company.app.username"#defineKEY_PASSWORD @"com.company.app.password"@implementationgetUUID+(NSString*)getUUID{NSString*strUUID=(NSString*)[KeyChainStore load:@"com.company.app.usernamepassword"];//首次執(zhí)行該方法時,uuid為空if([strUUID isEqualToString:@""]||!strUUID){//生成一個uuid的方法CFUUIDRef uuidRef=CFUUIDCreate(kCFAllocatorDefault);strUUID=(NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault,uuidRef));//將該uuid保存到keychain[KeyChainStore save:KEY_USERNAME_PASSWORD data:strUUID];}returnstrUUID;}@end

在Viewcontroller里面執(zhí)行如下代碼

#import"ViewController.h"#import"getUUID.h"@interfaceViewController()@end@implementationViewController-(void)viewDidLoad{[superviewDidLoad];NSLog(@" uuid? is? ---> %@",[getUUID getUUID]);// Do any additional setup after loading the view, typically from a nib.}

打印出來類似于以下的長串字符:

獲取到的uuid.png

把程序卸載掉然后重新運行一次,獲取到的還是上次保存的uuid.

不知道手機越獄以后,會不會改變,因為樓主手機版本是最新的9.3.5,身邊還沒相關越獄設備,希望大家可以自行測試一下.并告知樓主.聯(lián)系方式 : QQ :576484150

參考地址:

:http://blog.sina.com.cn/s/blog_5971cdd00102vqgy.html

:http://blog.csdn.net/chy555chy/article/details/51628079

:http://www.reibang.com/p/29572b756d26

寫了一個demo,已經放在gitHub上了,有興趣的同學可以下載下來瞅瞅.

demo 地址 :https://github.com/chengkunlun/getUUID

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末扶叉,一起剝皮案震驚了整個濱河市勿锅,隨后出現(xiàn)的幾起案子帕膜,更是在濱河造成了極大的恐慌,老刑警劉巖溢十,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泳叠,死亡現(xiàn)場離奇詭異,居然都是意外死亡茶宵,警方通過查閱死者的電腦和手機危纫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乌庶,“玉大人种蝶,你說我怎么就攤上這事÷鞔螅” “怎么了螃征?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長透敌。 經常有香客問我盯滚,道長,這世上最難降的妖魔是什么酗电? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任魄藕,我火速辦了婚禮,結果婚禮上撵术,老公的妹妹穿的比我還像新娘背率。我一直安慰自己,他們只是感情好嫩与,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布寝姿。 她就那樣靜靜地躺著,像睡著了一般划滋。 火紅的嫁衣襯著肌膚如雪饵筑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天处坪,我揣著相機與錄音根资,去河邊找鬼。 笑死稻薇,一個胖子當著我的面吹牛嫂冻,可吹牛的內容都是我干的。 我是一名探鬼主播塞椎,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼桨仿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了案狠?” 一聲冷哼從身側響起服傍,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤钱雷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吹零,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罩抗,經...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年灿椅,在試婚紗的時候發(fā)現(xiàn)自己被綠了套蒂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡茫蛹,死狀恐怖操刀,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情婴洼,我是刑警寧澤骨坑,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站柬采,受9級特大地震影響欢唾,放射性物質發(fā)生泄漏。R本人自食惡果不足惜粉捻,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一礁遣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杀迹,春花似錦亡脸、人聲如沸押搪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽大州。三九已至续语,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間厦画,已是汗流浹背疮茄。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留根暑,地道東北人力试。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像排嫌,于是被迫代替她去往敵國和親畸裳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內容