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

相关文章
相关标签/搜索