==== Apple公司于2013年5月1日开始,拒绝采集UDID的App上架App Store
==== iOS 5.0 之后uniqueIdentifier方法就被废弃掉了;
==== iOS 7.0 中苹果又封杀mac地址。
==== iOS 7.0 系统把粘贴板的访问权限限制在了同一个开发者的范围内OpenUDID失效.

所以说,现在想通过代码获取是不可能的了,如果你想看看你设备的UDID,可以通过iTunes来查看。

而且我们需要注意的一点是,对于已越狱了的设备,UDID并不是唯一的.使用Cydia插件UDIDFaker,可以为每一个应用分配不同的UDID.

所以UDID作为标识唯一设备就不要幻想了

目前最终方案:

idfv + keychain

或者

UUID + keychain

唯一缺点:用户抹掉iPhone数据,刷机或重装系统会让该id重置.

一.UDID(Unique Device Identifier)

UDID的全称是Unique Device Identifier,顾名思义,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和数字组成。每台iOS设备的UDID是唯一且永远不会改变。但是Unique Device Identifier 最早就被苹果封杀了,使用后上线会被拒绝。

那么有没有另外的办法来获取用户设备的唯一标识符呢?答案是有的,当然这样的标识符不是苹果隐藏的UDID了,使用OpenUDID开源代码,这个代码通过一些特殊的算法,创建了每一个设备的唯一标识符,你可以拿过来用来识别设备了。
但是.OpenUDID是用系统粘贴板作为中间存储供所有app调用.IOS7系统把粘贴板的访问权限限制在了同一个开发者的范围内,既同一个开发者的多个app在同个设备上共享粘贴板 ,所以OpenUDID已经不可用.

二.MAC Address

使用WiFi的mac地址来取代已经废弃了的uniqueIdentifier方法。具体可见:

http://stackoverflow.com/questions/677530/how-can-i-programmatically-get-the-mac-address-of-an-iphone

然而在iOS 7中苹果再一次无情的封杀mac地址,使用之前的方法获取到的mac地址全部都变成了02:00:00:00:00:00。

三.OPEN UDID

第三方最出名的莫过于此了,但是iOS7这货也无法使用了,由于iOS7对剪贴板(OpenUDID保存到剪贴版中)的限制,导致同一个设备上应用间,无法再共享一个OpenUDID。

OpenUDID原理:安装第一个OpenUDID开发的游戏App1,生成OpenUDID,安装第二款OpenUDID的App2,会从剪贴板中获取出之前生成的UDID,App1、App2都是使用的同一个UDID,但是如果删除所有OpenUDID的游戏后,重新安装App1,这时生成的UDID就已经重置了,和之前的已然不同,玩家的账号信息已丢失,要被投诉了……

当将设备上所有使用了OpenUDID方案的应用程序删除,且设备关机重启,xcode彻底清除并重启,重装应用程序去获取OpenUDID,此时OpenUDID变化,与之前不一样了

四.UUID(Universally Unique Identifier)

UUID是Universally Unique Identifier的缩写,中文意思是通用唯一识别码.
利用UUID获取设备唯一识别码有以下三种方式:

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或其它地方。

NSUUIDNSUUID在iOS 6中才出现,这跟CFUUID几乎完全一样,只不过它是Objective-C接口。+ (id)UUID 是一个类方法,调用该方法可以获得一个UUID。通过下面的代码可以获得一个UUID字符串:

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

跟CFUUID一样,这个值系统也不会存储,每次调用的时候都会获得一个新的唯一标示符。如果要存储的话,你需要自己存储。在我读取NSUUID时,注意到获取到的这个值跟CFUUID完全一样(不过也可能不一样):
示例: 68753A44-4D6F-1226-9C60-0050E4C00067
1,利用 NSUserDefaults 存取。

这种方法可以保证用户不删除软件情况下的获取同一个数据。因为NSUserDefaults 数据时保存在 沙盒里面的,会随着软件删除而被清空。UUID不好的地方就是用户删除了你开发的程序以后,基本上你就不可能获取之前的数据了。

UUID是基于iOS设备上面某个单个的应用程序,只要用户没有完全删除应用程序,则这个UUID在用户使用该应用程序的时候一直保持不变。如果用户删除了这个应用程序,然后再重新安装,那么这个UUID已经发生了改变。

2,通过调用[[UIDevice currentDevice]identifierForVendor];方法可以获取UUID。

此方法是官方6.0系统后推出的,指定唯一标示符号;不同软件,不同机器,运行的时候值都是不一样的;也就是说可以满足标识唯一性。

但是有一个问题需要注意,大部分正版的手机在软件卸载了、然后重新安装的情况下还是会保持和原先保存同一个值。但是对于有些越狱或者美版的手机 在卸载后仍然会重新获取数据。

3,Keychain方案
KeyChian 是保存在沙盒之外的存储数据,相当于Dictionary, 所有应用都可以获取和保存,因此当一个软件卸载之后完全不影响里面的数据,这样当软件重新安装之后,理所当然的可以获取里面的原数据。
这里我用的还是别人封装过的一些代码SFHFKeychainUtils(可以在网上任意下载):

//保存数据
BOOL s = [SFHFKeychainUtils storeUsername:name andPassword:pswd forServiceName:server updateExisting:NO error:nil];
//获取密码
NSString * psw = [SFHFKeychainUtils getPasswordForUsername:name andServiceName:server error:nil];

五.广告标示符(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
苹果推荐的就是使用IDFA、IDFV了,官方推荐那必然妥妥的了

idfa: 适用于对外:例如广告推广,换量等跨应用的用户追踪等

idfv: 适用于对内:例如分析用户在应用内的行为等

idfa:主要用于广告,可能会获取不到,iOS用户也可以 设置|隐私|广告追踪 里重置此id的值,虽然玩家一般不会重置,但是上述理由已经不足以把idfa作为账号了

idfv:顾名思义,是给Vendor标识用户用的,每个设备在所属同一个Vender的应用里,都有相同的值。其中的Vender是指应用提供商,但准确点说,是通过BundleID的DNS反转的前两部分进行匹配,如果相同就是同一个Vender,例如对于com.somecompany.appone,com.somecompany.apptwo 这两个BundleID来说,就属于同一个Vender,共享同一个idfv的值。和idfa不同的是,idfv的值是一定能取到的,所以非常适合于作为内部用户行为分析的主id,来标识用户,替代OpenUDID。

六.Vindor标示符 (IDFV-identifierForVendor)

全名:identifierForVendor
获取代码:

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

来源:iOS6.0及以后

说明:顾名思义,是给Vendor标识用户用的,每个设备在所属同一个Vender的应用里,都有相同的值。其中的Vender是指应用提供商,但准确点说,是通过BundleID的反转的前两部分进行匹配,如果相同就是同一个Vender,例如对于com.taobao.app1, com.taobao.app2 这两个BundleID来说,就属于同一个Vender,共享同一个idfv的值。和idfa不同的是,idfv的值是一定能取到的,所以非常适合于作为内部用户行为分析的主id,来标识用户,替代OpenUDID。

注意:如果用户将属于此Vender的所有App卸载,则idfv的值会被重置,即再重装此Vender的App,idfv的值和之前不同。

六.推送送token+bundle_id的方法:

1、应用中增加推送用来获取token
2、获取应用bundle_id
3、根据token+bundle_id进行散列运算

apple push token保证设备唯一,但必须有网络情况下才能工作,该方法不依赖于设备本身,但依赖于apple push,而苹果push有时候会抽风的。

总结

很不幸,上面所有这些表示设备唯一号的标识,在IOS7中要么被禁止使用,要么重新安装程序后两次获取的标识符不一样。

由于IOS系统存储的数据都是在sandBox里面,一旦删除App,sandBox也不复存在。好在有一个例外,那就是keychain(钥匙串)。

通常情况下,IOS系统用NSUserDefaults存储数据信息,但是对于一些私密信息,比如密码、证书等等,就需要使用更为安全的keychain了。

keychain里保存的信息不会因App被删除而丢失。所以,可以利用这个keychain这个特点来保存设备唯一标识。

那么,如何在应用里使用使用keyChain呢,我们需要导入Security.framework ,keychain的操作接口声明在头文件SecItem.h里。

直接使用SecItem.h里方法操作keychain,需要写的代码较为复杂,我们可以使用已经封装好了的工具类KeychainItemWrapper来对keychain进行操作。

KeychainItemWrapper是apple官方例子“GenericKeychain”里一个访问keychain常用操作的封装类,在官网上下载了GenericKeychain项目后,只需要把“KeychainItemWrapper.h”和“KeychainItemWrapper.m”拷贝到我们项目,并导入Security.framework 。KeychainItemWrapper的用法:

/** 初始化一个保存用户帐号的KeychainItemWrapper */
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Account Number"
accessGroup:@"YOUR_APP_ID_HERE.com.yourcompany.AppIdentifier"];
//保存数据
[wrapper setObject:@"<帐号>" forKey:(id)kSecAttrAccount];
[wrapper setObject:@"<帐号密码>" forKey:(id)kSecValueData];
//从keychain里取出帐号密码
NSString *password = [wrapper objectForKey:(id)kSecValueData];
//清空设置
[wrapper resetKeychainItem];

其中方法“- (void)setObject:(id)inObject forKey:(id)key;”里参数“forKey”的值应该是Security.framework 里头文件“SecItem.h”里定义好的key,用其他字符串做key程序会出错!

【IOS】获取iOS设备唯一标识的演进UDID, MAC Address,UUID,IDFA,IDFV,OpenUDID相关推荐

  1. 获取android设备唯一编号_如何获取Android设备唯一标识码教程

    ID的全称是(Virtual identity electronic identification),中文名为通用账户,是俗称的网络身份证.它是一种互联网身份认证协议,其具有唯一性和信息不可否认性.I ...

  2. 获取Android设备唯一标识

    很多情况下,需要将APP和设备进行绑定,以保证用户不会无限制的注册或发送请求.然而,Android设备并没有绝对的唯一标识. Android提供了多种方法来获取所谓的唯一标识.常用的有六种. (1)A ...

  3. 获取Android设备唯一标识码

    概述 有时需要对用户设备进行标识,所以希望能够得到一个稳定可靠并且唯一的识别码.虽然Android系统中提供了这样设备识别码,但是由于Android系统版本.厂商定制系统中的Bug等限制,稳定性和唯一 ...

  4. 获取安卓设备唯一标识码并存储在SharedPRreferences中

    前言:设备登陆时提供设备序列号信息传到后端,安卓设备日新月异,一些设备仅支持wifi上网即没插卡功能,且互联网企业APP根本无法限制统一用户设备,用户可使用虚拟机不断创建新模拟器来伪装成新设备用于注册 ...

  5. 获取Android设备唯一标识(唯一序列号)

    有很多场景和需求你需要用到手机设备的唯一标识符. 在Android中,有以下几种方法获取这样的ID. 1. The IMEI: 仅仅只对Android手机有效: 1 2 TelephonyManage ...

  6. [Android][获取Android设备唯一标识]

    1.落笔缘由 最近需要获取能够标志Android设备的唯一标识,但是由于Android系统版本不同或者root等诸多原因,造成有些设备标识为NULL或者标识相同的问题,在网上搜索了相关资料,总结一下各 ...

  7. php 手机唯一标示_Php获取移动设备唯一标识

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 function is_mobile_request() { $_SERVER['ALL_HTTP'] = isset($_SERVER['ALL_HTT ...

  8. php如何获取手机序列号,Php获取移动设备唯一标识

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 function is_mobile_request() { $_SERVER['ALL_HTTP'] = isset($_SERVER['ALL_HTT ...

  9. iOS设备唯一标识获取策略(不定时更新)

    在iOS系统中,获取设备唯一标识的方法有很多: 一.UDID(Unique Device Identifier) UDID的全称是Unique Device Identifier,它就是苹果IOS设备 ...

  10. 转-ios设备唯一标识获取策略

    [http://www.2cto.com/kf/201308/237648.html] 英文原文:In iOS 7 and later, if you ask for the MAC address ...

最新文章

  1. edgeR:一个数字基因表达数据差异表达分析Bioconductor程序包
  2. 考夫曼:破解大脑代码并创建真正的人工智能
  3. 拔最多的鹅毛,听最少的鹅叫
  4. 天线巴伦制作和原理_一种基于LTCC技术的新型Marchand巴伦滤波器
  5. Linux下Nginx编译安装后的开机自启动设置
  6. 基于Windows Server 2008 R2的WSFC实现SQL Server 2012高可用性组(AlwaysOn Group)
  7. 基于FPGA的UART接口协议设计
  8. 单步调试理解webpack里通过require加载nodejs原生模块实现原理
  9. 视觉标定,再来一波!!更简单粗暴!!!!!!
  10. tinyid 教程_tinyid
  11. 如何进行 node.js 的 安装与卸载
  12. 在 Windows Azure 上部署预配置 Oracle VM
  13. poj 2506 Tiling dp 递推
  14. 公司员工后台管理系统界面设计-Axure9原型设计
  15. 语音交互的基本概念和设计实践
  16. JS去除输入文本的所有空格、逗号、换行符等空白字符
  17. Unity之IOS和Android安装包大小优化
  18. 如何编译PHP源代码?
  19. 天地不仁,以万物为刍狗--[1971年萨姆派金帕暴力电影代表作][稻草狗/大丈夫]...
  20. 省住建厅关于做好二级建造师电子化注册管理工作的通知〔2018〕994号

热门文章

  1. 斗破特别篇美杜莎建模赏析文
  2. 国内缺少一个slideshare
  3. 程序员网站运营手册1
  4. 想不到吧,实体类能自己CRUD,MyBatis-Plus AR模式了解下
  5. word 单独设置正文页码
  6. 注册一个北京公司可以申请办理京牌吗,好申请吗?
  7. MySQL面试夺命连环27问
  8. php拆分excel,PHPExcel合并与拆分单元格的方法
  9. java 逃逸_Java 逃逸分析
  10. 承上启下继往开来,Python3上下文管理器(ContextManagers)与With关键字的迷思