UUID 浅析
在2013年3月21日苹果已经通知开发者,从2013年5月1日起,访问UIDID的应用将不再能通过审核,替代的方案是开发者应该使用“在iOS 6中介绍的Vendor或Advertising标示符”。
unique Identifier即将退出,苹果给了我们Vendor和Advertising identifier两个选择,但应该用哪一个?文档并没有给出确切答案,具体使用哪个完全由你根据自己app的目的来决定。下面我将列出iOS中目前支持的,以及被废弃的唯一标示符方法,并对其做出相应的解释,希望可以帮你做出正确的确定。
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, Pasteboard或其它地方。
NSUUID
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];
跟CFUUID和NSUUID不一样,广告标示符是由系统存储着的。不过即使这是由系统存储的,但是有几种情况下,会重新生成广告标示符。如果用户完全重置系统((设置程序 -> 通用 -> 还原 -> 还原位置与隐私) ,这个广告标示符会重新生成。另外如果用户明确的还原广告(设置程序-> 通用 -> 关于本机 -> 广告 -> 还原广告标示符) ,那么广告标示符也会重新生成。关于广告标示符的还原,有一点需要注意:如果程序在后台运行,此时用户“还原广告标示符”,然后再回到程序中,此时获取广告标示符并不会立即获得还原后的标示符。必须要终止程序,然后再重新启动程序,才能获得还原后的广告标示符。之所以会这样,我猜测是由于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是什么”。我首先想到的是苹果开发者账号。但事实证明这是错误的。接着我想可能是有一个AppIdentifierPrefix东西,跟钥匙串访问一样,可以在多个程序间共享。同样,这个想法也是的。最后证明,vendor非常简单:一个Vendor是CFBundleIdentifier(反转DNS格式)的前两部分。例如,com.doubleencore.app1 和 com.doubleencore.app2 得到的identifierForVendor是相同的,因为它们的CFBundleIdentifier 前两部分是相同的。不过这样获得的identifierForVendor则完全不同:com.massivelyoverrated 或 net.doubleencore。
在这里,还需要注意的一点就是:如果用户卸载了同一个vendor对应的所有程序,然后在重新安装同一个vendor提供的程序,此时identifierForVendor会被重置。
示例: 599F9C00-92DC-4B5C-9464-7971F01F8370
UDID
在之前的版本中是可用的,但是在iOS5以及之后的版本中,以及被弃用了。虽然,这个UDID用得很广泛,但是,不得不说的是,它在慢慢的远离开发者,不能在考虑使用UDID了。至于这个标示符是转为私有方法,或者完全从以后的iOS版本中移除,还有待观察。不过,这个UDID在部署企业级签名程序时,非常方便。获取UDID的方法如下:
NSString *udid = [[UIDevice currentDevice] uniqueIdentifier];
示例: bb4d786633053a0b9c0da20d54ea7e38e8776da4
OpenUDID
在iOS 5发布时,uniqueIdentifier被弃用了,这引起了广大开发者需要寻找一个可以替代UDID,并且不受苹果控制的方案。由此OpenUDID成为了当时使用最广泛的开源UDID替代方案。OpenUDID在工程中实现起来非常简单,并且还支持一系列的广告提供商。
NSString *openUDID = [OpenUDID value];
OpenUDID利用了一个非常巧妙的方法在不同程序间存储标示符 — 在粘贴板中用了一个特殊的名称来存储标示符。通过这种方法,别的程序(同样使用了OpenUDID)知道去什么地方获取已经生成的标示符(而不用再生成一个新的)。
之前已经提到过,在将来,苹果将开始强制使用advertisingIdentifier 或identifierForVendor。如果这一天到来的话,即使OpenUDID看起来是非常不错的选择,但是你可能不得不过渡到苹果推出的方法。
示例: 0d943976b24c85900c764dd9f75ce054dc5986ff
总结
希望上面的信息能够帮助你在程序使用选择正确的唯一标示符。在这里,我创建了一个小的唯一标示符测试程序,你可以运行该程序,并查看一下显示的内容(包括上面提到的所有标示符)。另外,下面有两个表,表中描述了两个内容:在iOS中的可用性,以及什么时候可以获得重置的标示符。

* 程序必须重启才能看到改变的效果。
** 删除了所有相同vendor提供的程序,才能看到改变的值。
代码如下:
//内连,使用情况较多下使用,
static inline NSString * GetUUIDString()
{
CFUUIDRef uuidObj = CFUUIDCreate(nil);
NSString *uuidString = (__bridge_transfer NSString*)CFUUIDCreateString(nil, uuidObj);
CFRelease(uuidObj);
return uuidString;
}
//类方法,建议新建NSString的分类使用,
+ (NSString*) getUUIDString
{
CFUUIDRef uuidObj = CFUUIDCreate(nil);
NSString *uuidString = (__bridge_transfer NSString*)CFUUIDCreateString(nil, uuidObj);
CFRelease(uuidObj);
return uuidString;
}
参考链接:
1.http://www.jianshu.com/p/47e6cbc34d85
2.http://hulefei29.iteye.com/blog/1862306
3.http://blog.csdn.net/shouqiangwei/article/details/42239765
UUID 浅析的更多相关文章
- 分布式锁----浅析redis实现
引言大概两个月前小伙伴问我有没有基于redis实现过分布式锁,之前看redis的时候知道有一个RedLock算法可以实现分布式锁,我接触的分布式项目要么是github上开源学习的,要么是小伙伴们公司项 ...
- Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23363591来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...
- Android5.0(Lollipop) BLE蓝牙4.0+浅析code(二)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23347612来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...
- 浅析 fstab 与移动硬盘挂载方法
本文转自 Steins;Lab,非常详细地介绍了树莓派上 fstab 的配置项. 近期自己的Raspberry Pi出了点问题,总结总结便有了这篇文章. 本文首先记录“移动硬盘挂载”实际发生的问题,然 ...
- 浅析CopyOnWriteArrayList
CopyOnWriteArrayList引入 模拟传统的ArrayList出现线程不安全的现象 public class Demo1 { public static void main(String[ ...
- 浅析Java7中的ConcurrentHashMap
引入ConcurrentHashMap 模拟使用hashmap在多线程场景下发生线程不安全现象 import java.util.HashMap; import java.util.Map; impo ...
- binlog浅析
binlog浅析 一.基础知识 什么是binlog? (图一) 全称:Binary Log (二进制日志),包含描述数据库更改的" 事件 ",例如表创建操作或对表数据的更改.二进制 ...
- SQL Server on Linux 理由浅析
SQL Server on Linux 理由浅析 今天的爆炸性新闻<SQL Server on Linux>基本上在各大科技媒体上刷屏了 大家看到这个新闻都觉得非常震精,而美股,今天微软开 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
随机推荐
- #include 和 #pragma comment 的相对路径起点
#include 是以当前文件所在路径为当前目录 #pragma comment 是以当前工程所在路径为当前目录 #include "../../../../ThirdParty/Inclu ...
- Openjudge-计算概论(A)-整数奇偶排序
描述: 输入10个整数,彼此以空格分隔重新排序以后输出(也按空格分隔),要求:1.先输出其中的奇数,并按从大到小排列:2.然后输出其中的偶数,并按从小到大排列.输入任意排序的10个整数(0-100), ...
- Openjudge-计算概论(A)-点与正方形的关系
描述: 有一个正方形,四个角的坐标(x,y)分别是(1,-1),(1,1),(-1,-1),(-1,1),x是横轴,y是纵轴.写一个程序,判断一个给定的点是否在这个正方形内.输入输入坐标x,y输出ye ...
- BcdTool(系统启动菜单管理器) v1.0912 绿色版
软件名称: 系统启动菜单管理器(BcdTool)软件语言: 简体中文授权方式: 免费软件运行环境: Win 32位/64位软件大小: 903KB图片预览: 软件简介:BcdTool是一款windows ...
- genymotion模拟器配置X86模拟器加速器
网上下载zip包 http://download.csdn.net/download/we5868123/9430140 直接拖进去即可,虚拟机不能使用管理员权限启动 名字为:解决genymotion ...
- 第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列。 例如: List list = new ArrayList(); list.add(“Hello”); list.add(“World”); list.add(“Learn”); //此时list 为Hello World Learn r
package zuoye; import java.util.ArrayList; import java.util.List; public class Reverse01 { public st ...
- Qt主窗体显示最前
在delphi中使用Application.BringToFront;可以保证当前程序显示在最前. 然而今天在Qt中,没有类似函数供调用. 尝试了activeWindow,show,showNorma ...
- CentOS的KVM实践(虚拟机创建、网桥配置、Spice)
最近公司准备上一套基于openstack的虚拟桌面系统,作为该项目的负责人,觉得有必要自己实践一下,该系统的搭建.最基础的就是需要了解基于linux的kvm的实践. 一.基础软件包准备 系统是采用px ...
- 快速破解ps方法
1.首先现在ps安装包和破解包. 2.运行Block Adobe Activation,防止ADOBE激活程序启动,按操作提示即可. 3.运行Adobe CS6安装程序. 4.选择“试用”. 5.输入 ...
- HDU - 5547 Sudoku(数独搜索)
Description Yi Sima was one of the best counselors of Cao Cao. He likes to play a funny game himself ...