UDID 和 UUID 的問題

1、UDID 全名  Unique Device Identifier :設備惟一標識符。UDID是和設備有關的,並且是隻和設備有關的,有點相似於電腦的MAC地址。真機調試中咱們須要把UDID這個東西添加到Provisoning Profile受權文件中,也就是把設備惟一標識符添加進去,以此來識別某一臺設備。ios

UDID是一個40位十六進制序列,咱們可使用 iTunes 和 Xcode 來獲取這個值。git

 

(1)iTunes獲取UDID:github

  設備連上電腦,打開iTunes.服務器

注意:默認這個位置顯示的是序列號,只要點擊一下序列號(紅色箭頭處)的位置,就能夠切換爲UDID了網絡

 

(2)Xcode獲取UDID:app

把設備連上電腦,而後打開Xcode,選擇Window-->Devices,就會顯示出當前你鏈接上的全部設備,其中顯示的Identifier就是該設備的UDID:框架

上面是經過設備直接查看獲得的,若是咱們要在代碼中訪問UDID,怎麼作呢?less

ios5 sdk中的獲取方法: ide

[UIDevice currentDevice] uniqueIdentifier];工具

對於已越獄了的設備,UDID並非惟一的.使用Cydia插件UDIDFaker,能夠爲每個應用分配不一樣的UDID. 

因此UDID做爲標識惟一設備的用途已經不大了. 

 

2、UUID全名 Universally Unique Identifier的縮寫,中文意思是通用惟一識別碼。

 

很遺憾,自從iOS5以後,蘋果就禁止了經過代碼訪問UDID,在這以前,可使用[[UIDevice cuurrent] uniqueIdenfier] 這個方法來獲取某設備UDID,如今是不可能了。對於爲何要禁止訪問UDID,我下面會提到。

 

CFUUID 從iOS2.0開始,CFUUID就有了。它是CoreFoundatio包的一部分,所以API屬於C語言風格。CFUUIDCreate 方法用來建立CFUUIDRef,而且能夠得到一個相應的 NSString,代碼以下:

  • CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault); 
  • NSString *cfuuidString =(NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));

得到的這個CFUUID值系統並無存儲每次調用CFUUIDCreate,系統都會返回一個的惟一標示符。若是你但願存儲這個標示符,那麼須要本身將其存儲到NSUserDefaults, Keychain,或其它地方。

示例: 68753A44-4D6F-1226-9C60-0050E4C00067

 

NSUUID在iOS 6中才出現,這跟CFUUID幾乎徹底同樣,只不過它是Objective-C接口。+ (id)UUID 是一個類方法,調用該方法能夠得到一個UUID。經過下面的代碼能夠得到一個UUID字符串:

  • NSString *uuid = [[NSUUID UUID] UUIDString];

CFUUID同樣,這個值系統也不會存儲每次調用的時候都會得到一個的惟一標示符。若是要存儲的話,你須要本身存儲。在我讀取NSUUID時,注意到獲取到的這個值跟CFUUID徹底同樣(不過也可能不同):

示例: 68753A44-4D6F-1226-9C60-0050E4C00067

 

廣告標示符(IDFA-identifierForIdentifier)這是iOS 6中另一個新的方法,advertisingIdentifier 是新框架AdSupport.framework的一部分。ASIdentifierManager單例提供了一個方法advertisingIdentifier,經過調用該方法會返回一個上面提到的NSUUID實例。

  • NSString *adId =[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

CFUUIDNSUUID不同,廣告標示符是由系統存儲着的。不過即便這是由系統存儲的,可是有幾種狀況下,會從新生成廣告標示符。若是用戶徹底重置系統((設置程序 -> 通用 -> 還原 -> 還原位置與隱私) ,這個廣告標示符會從新生成。另外若是用戶明確的還原廣告(設置程序-> 通用 -> 關於本機 -> 廣告 -> 還原廣告標示符) ,那麼廣告標示符也會從新生成。關於廣告標示符的還原,有一點須要注意:若是程序在後臺運行,此時用戶「還原廣告標示符」,而後再回到程序中,此時獲取廣告標示符並不會當即得到還原後的標示符。必需要終止程序,而後再從新啓動程序,才能得到還原後的廣告標示符。之因此會這樣,我猜想是因爲ASIdentifierManager是一個單例。

針對廣告標示符用戶有一個可控的開關「限制廣告跟蹤」。Nick Arnott的文章中已經指出了。將這個開關打開,實際上什麼也沒有作,不過這是但願限制你訪問廣告標示符。這個開關是一個簡單的boolean標誌,當將廣告標示符發到任意的服務器端時,你最好判斷一下這個值,而後再作決定。

示例: 1E2DFA89-496A-47FD-9941-DF1FC4E6484A

 

Vindor標示符 (IDFV-identifierForVendor)這種叫法也是在iOS 6中新增的,不過獲取這個IDFV的新方法被添加在已有的UIDevice類中。跟advertisingIdentifier同樣,該方法返回的是一個NSUUID對象。

  • NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

蘋果官方的文檔中對identifierForVendor有以下這樣的一段描述 :

The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor.

 

相同的程序-相同的vindor-相同的設備,那麼獲取到的這個屬性值就不會變

相同的程序-相同的設備-不一樣的vindor,或 相同的程序-不一樣的設備-不管是否相同的vindor 那麼這個值是不一樣的:。

(vendor很是簡單:一個Vendor是CFBundleIdentifier(反轉DNS格式)的前兩部分。例如,com.doubleencore.app1 和 com.doubleencore.app2 獲得的identifierForVendor是相同的,由於它們的CFBundleIdentifier 前兩部分是相同的。)

在這裏,還須要注意的一點就是:若是用戶卸載了同一個vendor對應的全部程序,而後在從新安裝同一個vendor提供的程序,此時identifierForVendor會被重置。

示例: 599F9C00-92DC-4B5C-9464-7971F01F8370

 

重點:上面的IDFV方法中

這個identifierForVendor應用設備二者都有關的,A應用安裝到張三這臺設備上,就會產生一個identifierForVendor(好比是:1234);A應用安裝到李四這臺設備上,就會產生另外一個identifierForVendor(好比是:5678);B應用安裝到張三這臺設備上,又是一個全新的identifierForVendor(好比是:9999),B應用安裝到李四這臺設備上,仍是一個全新的identifierForVendor(好比是:7777)。  因此咱們知道,這個identifierForVendor是一種應用加設備綁定產生的標識符,至關因而:Z(identifierForVendor) = X(某應用) + Y(某設備)。 固然,和真正的UDID的區別是顯而易見的:也就是說App的開發者沒有辦法去區分某一臺設備了,而是隻能識別某個應用在某臺設備上。且UUID每次生成的值都不同,須要開發者自行保存UUID. 

若是使用UUID爲標識保存用戶的資料在網絡上,當用戶卸載軟件重裝軟件後,UUID的值就可能會發生改變(基本上可說是百分百會發生改變),用戶則沒法從新下載原來的網絡資料。

 

三.一個可行的解決方案 

大多數應用都會用到蘋果設備的UDID號,UDID一般有如下兩種用途:

1)用於一些統計與分析目的;【第三方統計工具如友盟,廣告商如ADMOB等】

2)將UDID做爲用戶ID來惟一識別用戶,省去用戶名,密碼等註冊過程。

 

可是由於UUID的特性,不能解決這種問題,如今網上有一現成的解決方案,使用設備的Mac地址,由於Mac地址也是惟一的.unix有系統調用能夠獲取Mac地址.但有些事情須要注意: 

1.iPhone可能有多個Mac地址,wifi的地址,以及SIM卡的地址.通常來說,咱們取en0的地址,由於他是iPhone的wifi的地址,是確定存在的.(例外狀況依然有:市面上依然存在一部分聯通的閹割版無wifi的iPhone) 

2.Mac地址涉及到隱私,不該該胡亂將用戶的Mac地址傳播!因此咱們須要將Mac地址進行hash以後,才能做爲DeviceId上傳. 

 

關於第一個注意點的問題,通過我測試,沒有Wifi功能的iPhone3GS同樣能夠得到Mac地址,因此這應該是目前標識設備惟一最好的一個解決方案. 

 

 

解決方案github下載地址github。https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5

該方案提供了兩個方法:

uniqueDeviceIdentifier (返回MAC和CFBundleIdentifier的MD5值)

uniqueGlobalDeviceIdentifier(返回MAC的MD5值)

 

使用方法:

#import "UIDevice+IdentifierAddition.h"

NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]);

NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);

 

 

測試結果:

WIFI下:

UDID:XXXX21f1f19edff198e2a2356bf4XXXX 

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX 

 

3G下:

UDID:XXXX21f1f19edff198e2a2356bf4XXXX

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX

 

GPRS下

UDID:XXXX21f1f19edff198e2a2356bf4XXXX

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX

 

飛行模式下:

UDID:XXXX21f1f19edff198e2a2356bf4XXXX

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX

 

刪除應用重裝後:

UDID:XXXX21f1f19edff198e2a2356bf4XXXX

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX

相關文章
相關標籤/搜索