iOS怎樣獲取設備唯一標識符

開篇

我又來寫簡書了,今天說一下設備的唯一識別碼,和怎么使用它吧。IOS系統中,獲取設備唯一標識的方法有很多,我們來介紹一下。

各種設備識別碼的介紹

  • UDID(Unique Device Identifier)
    UDID的全稱是Unique Device Identifier,顧名思義,它就是蘋果IOS設備的唯一識別碼,它由40個字符的字母和數字組成。
  • UUID(Universally Unique Identifier)
    UUID是Universally Unique Identifier的縮寫,中文意思是通用唯一識別碼.
  • MAC Address
    MAC(Media Access Control或者Medium Access Control)地址,意譯為媒體訪問控制,或稱為物理地址、硬件地址,用來定義網絡設備的位置。在OSI模型中,第三層網絡層負責 IP地址,第二層數據鏈路層則負責 MAC地址。因此一個主機會有一個MAC地址,而每個網絡位置會有一個專屬于它的IP地址。MAC地址是網卡決定的,是固定的。
  • OPEN UDID
    設備的識別碼,每臺iOS設備的OpenUDID是通過第一個帶有OpenUDID SDK包的App生成,如果你完全刪除全部帶有OpenUDID SDK包的App(比如恢復系統等),那么OpenUDID會重新生成,而且和之前的值會不同,相當于新設備;
    優點是沒有用到MAC地址;不同設備能夠獲取各自唯一的識別碼,保證了唯一性,可以用于以往UDID的相關用途;從代碼分析OpenUDID的獲取,識別碼獲取方便并且保存謹慎。缺點是當將設備上所有使用了OpenUDID方案的應用程序刪除,且設備關機重啟,xcode徹底清除并重啟,重裝應用程序去獲取OpenUDID,此時OpenUDID變化,與之前不一樣了,所有OpenUDID應用卸載后,由UIPasteboard保存的數據即被清除,重裝故會重新獲取新的OpenUDID。
    那么當因為用戶干預或者惡意程序,致使UIPasteboard數據清除,從而導致OpenUDID被刪除,重裝也會獲取新的OpenUDID。
  • 廣告標示符(IDFA-identifierForIdentifier)
    廣告標示符,適用于對外:例如廣告推廣,換量等跨應用的用戶追蹤等。
  • Vindor標示符 (IDFV-identifierForVendor)
    Vendor是CFBundleIdentifier(反轉DNS格式)的前兩部分。來自同一個運營商的應用運行在同一個設備上,此屬性的值是相同的;不同的運營商應用運行在同一個設備上值不同。
    經測試,只要設備上有一個tencent的app,重新安裝后的identifierForVendor值不變,如果tencent的app全部刪除,重新安裝后的identifierForVendor值改變。

分析

雖然我們看似有了那么多的唯一標識,但是不要高興的太早,上面所有這些表示設備唯一號的標識,在IOS7中要么被禁止使用,要么重新安裝程序后兩次獲取的標識符不一樣。
下面就項目中的事來說一下,我的成(辛)長(酸)歷(歷)程(史)。之前的一個項目中要與無線WIFI設備對接,來控制用戶使用無線網絡的情況,但是,硬件那邊來的技術小哥一口咬定要實現這個必須要設備的Mac地址,因為他們的無線設備就是根據mac地址來實現控制的,然后對我進行了瘋狂的灌輸,Mac地址的用處...此處省略無數字,但是我想說的是,高傲的蘋果不允許啊,蘋果已經不允許獲取用戶的Mac地址了,在iOS請求的Mac地址都會返回一個固定的值,你不是要用來用戶識別么,你識別啊,在iOS7后返回一臉的02:00:00:00:00:00。一切的轉機直到我聯系到了他們的技術總監,一個大一號的程序猿(~_ ~),然后事情就解決了,其實通過別的唯一標識符也是可以的。
UDID,Mac地址,OpenUDID,都已經要么無效要么禁止,那么我們就采用目前用的比較多的UUID吧。

UUID使用

首先我么要獲取設備的UUID啊,這個還是比較簡單的,上代碼

    NSString *deviceUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

    NSLog(@"%@",deviceUUID);

這樣我們就打印出了設備的UUID

2016-08-02 15:13:14.138 keychaintest[2002:222100] BDAF6B4D-5DC0-4AEF-BCF8-6C7EFC94DE97

但是問題來了,當我們從真機上卸載這個軟件重新安裝的時候,UUID變了(模擬器每次都變),對,確實變了


圖片1.jpg

我們如果還要用UUID來作為唯一識別符的話,我們只能把他存在一個地方,讓軟件卸載的時候他也不會丟失,NSUserDefaults和FMDB等本地存儲已經不能再完成他們的使命了。怎么辦呢?

keychain的使用

keychain的使用確實幫我們解決了這個問題,我們可以在第一次生成我們需要的UUID的時候,保存他,然后就用keychain里保存的值來代替他的UUID,這樣卸載之后,生成新的UUID,但是keychain里的數據是不會消失的,這樣就實現了唯一識別碼的目的。
文檔上說iOS的keyChain是一個相對獨立的空間,當程序替換,刪除時并不會刪除keyChain的內容,這個要比Library/Cache好。刷機,恢復出廠應該就沒有了。關于備份,?只會備份數據,到那時不會備份設備的密鑰,換句話說,即使拿到數據,也沒有辦法解密里面的內容,感覺keyChain像是沙盒的升級版,可以存放一些非私密的信息,即使破解也不影響其它用戶,只影響那個破解了的設備。(比如針對該設備的一個密鑰)。
可訪問性一般來說,自己的程序只能訪問自己的keychain,相同bundle的程序通過設置group可以互相共享同組的keychain,從而實現程序間可以共同訪問一些數據。
說了那么多我們怎么使用它呢,蘋果給出了文檔,但是我們只是做簡單的數據的存儲,自己寫個簡單的類來實現它就好了。

GSKeyChainDataManager_h.png

然后實現它

GSKeyChainDataManager_m.png

這樣我們再調用它

 [GSKeyChainDataManager saveUUID:deviceUUID];  //存入
 [GSKeyChainDataManager readUUID] //讀取

進入設備的時候存入UUID,以后的時候讀取他。就算卸載,讀取出來的值還是第一次進入軟件的時候的UUID,實現了設備的唯一標識符。(注意寫的地方,不要每次運行都重新存儲,不要用模擬器)。

后記

keychain是非常有用的,可以幫我們保存用戶的賬號密碼等信息,我們可以通過自己寫的方法去存儲他。實現本地化保存,比以前的方法更加的安全哦。這里,如果有需要方法代碼的小伙伴,可以留下郵箱。

最新補充

最近由于工作以及各方面原因比較忙,所以很多留言也未發代碼,這里留一個git地址,有需要的自己去下載一下吧。SomeTools-Demo里面有幾個類似于工具類的代碼,比如正則表達式,定時器的封裝,GCD等知識,其中keychaintest是保存設備唯一標識符的代碼,有需要的可以去下一下,順便點個星哦,不用再留言了。

更正

此處的UUID 根本不是UUID ,是IDFV,設備的唯一標識用IDFV配合keychain來做的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容