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,代碼以下:
得到的這個CFUUID值系統並無存儲。每次調用CFUUIDCreate,系統都會返回一個新的惟一標示符。若是你但願存儲這個標示符,那麼須要本身將其存儲到NSUserDefaults, Keychain,或其它地方。 示例: 68753A44-4D6F-1226-9C60-0050E4C00067 |
NSUUID在iOS 6中才出現,這跟CFUUID幾乎徹底同樣,只不過它是Objective-C接口。+ (id)UUID 是一個類方法,調用該方法能夠得到一個UUID。經過下面的代碼能夠得到一個UUID字符串:
跟CFUUID同樣,這個值系統也不會存儲,每次調用的時候都會得到一個新的惟一標示符。若是要存儲的話,你須要本身存儲。在我讀取NSUUID時,注意到獲取到的這個值跟CFUUID徹底同樣(不過也可能不同): 示例: 68753A44-4D6F-1226-9C60-0050E4C00067 |
廣告標示符(IDFA-identifierForIdentifier)這是iOS 6中另一個新的方法,advertisingIdentifier 是新框架AdSupport.framework的一部分。ASIdentifierManager單例提供了一個方法advertisingIdentifier,經過調用該方法會返回一個上面提到的NSUUID實例。
跟CFUUID和NSUUID不同,廣告標示符是由系統存儲着的。不過即便這是由系統存儲的,可是有幾種狀況下,會從新生成廣告標示符。若是用戶徹底重置系統((設置程序 -> 通用 -> 還原 -> 還原位置與隱私) ,這個廣告標示符會從新生成。另外若是用戶明確的還原廣告(設置程序-> 通用 -> 關於本機 -> 廣告 -> 還原廣告標示符) ,那麼廣告標示符也會從新生成。關於廣告標示符的還原,有一點須要注意:若是程序在後臺運行,此時用戶「還原廣告標示符」,而後再回到程序中,此時獲取廣告標示符並不會當即得到還原後的標示符。必需要終止程序,而後再從新啓動程序,才能得到還原後的廣告標示符。之因此會這樣,我猜想是因爲ASIdentifierManager是一個單例。 針對廣告標示符用戶有一個可控的開關「限制廣告跟蹤」。Nick Arnott的文章中已經指出了。將這個開關打開,實際上什麼也沒有作,不過這是但願限制你訪問廣告標示符。這個開關是一個簡單的boolean標誌,當將廣告標示符發到任意的服務器端時,你最好判斷一下這個值,而後再作決定。 示例: 1E2DFA89-496A-47FD-9941-DF1FC4E6484A |
Vindor標示符 (IDFV-identifierForVendor)這種叫法也是在iOS 6中新增的,不過獲取這個IDFV的新方法被添加在已有的UIDevice類中。跟advertisingIdentifier同樣,該方法返回的是一個NSUUID對象。
蘋果官方的文檔中對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