首页 > 代码库 > 获取iOS设备唯一标识
获取iOS设备唯一标识
获取iOS设备唯一标识
<style>body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-top: 10px; padding-bottom: 10px; background-color: white; padding: 30px } body>*:first-child { margin-top: 0 !important } body>*:last-child { margin-bottom: 0 !important } a { color: #4183C4 } a.absent { color: #cc0000 } a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute; top: 0; left: 0; bottom: 0 } h1,h2,h3,h4,h5,h6 { margin: 20px 0 10px; padding: 0; font-weight: bold; cursor: text; position: relative } h1:hover a.anchor,h2:hover a.anchor,h3:hover a.anchor,h4:hover a.anchor,h5:hover a.anchor,h6:hover a.anchor { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA09pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoMTMuMCAyMDEyMDMwNS5tLjQxNSAyMDEyLzAzLzA1OjIxOjAwOjAwKSAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUM2NjlDQjI4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUM2NjlDQjM4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5QzY2OUNCMDg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5QzY2OUNCMTg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsQhXeAAAABfSURBVHjaYvz//z8DJYCRUgMYQAbAMBQIAvEqkBQWXI6sHqwHiwG70TTBxGaiWwjCTGgOUgJiF1J8wMRAIUA34B4Q76HUBelAfJYSA0CuMIEaRP8wGIkGMA54bgQIMACAmkXJi0hKJQAAAABJRU5ErkJggg==") no-repeat 10px center; text-decoration: none } h1 tt,h1 code { font-size: inherit } h2 tt,h2 code { font-size: inherit } h3 tt,h3 code { font-size: inherit } h4 tt,h4 code { font-size: inherit } h5 tt,h5 code { font-size: inherit } h6 tt,h6 code { font-size: inherit } h1 { font-size: 28px; color: black } h2 { font-size: 24px; border-bottom: 1px solid #cccccc; color: black } h3 { font-size: 18px } h4 { font-size: 16px } h5 { font-size: 14px } h6 { color: #777777; font-size: 14px } p,blockquote,ul,ol,dl,li,table,pre { margin: 15px 0 } hr { background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC") repeat-x 0 0; border: 0 none; color: #cccccc; height: 4px; padding: 0 } body>h2:first-child { margin-top: 0; padding-top: 0 } body>h1:first-child { margin-top: 0; padding-top: 0 } body>h1:first-child+h2 { margin-top: 0; padding-top: 0 } body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child { margin-top: 0; padding-top: 0 } a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6 { margin-top: 0; padding-top: 0 } h1 p,h2 p,h3 p,h4 p,h5 p,h6 p { margin-top: 0 } li p.first { display: inline-block } li { margin: 0 } ul,ol { padding-left: 30px } ul :first-child,ol :first-child { margin-top: 0 } dl { padding: 0 } dl dt { font-size: 14px; font-weight: bold; font-style: italic; padding: 0; margin: 15px 0 5px } dl dt:first-child { padding: 0 } dl dt>:first-child { margin-top: 0 } dl dt>:last-child { margin-bottom: 0 } dl dd { margin: 0 0 15px; padding: 0 15px } dl dd>:first-child { margin-top: 0 } dl dd>:last-child { margin-bottom: 0 } blockquote { border-left: 4px solid #dddddd; padding: 0 15px; color: #777777 } blockquote>:first-child { margin-top: 0 } blockquote>:last-child { margin-bottom: 0 } table { padding: 0; border-collapse: collapse } table tr { border-top: 1px solid #cccccc; background-color: white; margin: 0; padding: 0 } table tr:nth-child(2n) { background-color: #f8f8f8 } table tr th { font-weight: bold; border: 1px solid #cccccc; margin: 0; padding: 6px 13px } table tr td { border: 1px solid #cccccc; margin: 0; padding: 6px 13px } table tr th :first-child,table tr td :first-child { margin-top: 0 } table tr th :last-child,table tr td :last-child { margin-bottom: 0 } img { max-width: 100% } span.frame { display: block; overflow: hidden } span.frame>span { border: 1px solid #dddddd; display: block; float: left; overflow: hidden; margin: 13px 0 0; padding: 7px; width: auto } span.frame span img { display: block; float: left } span.frame span span { clear: both; color: #333333; display: block; padding: 5px 0 0 } span.align-center { display: block; overflow: hidden; clear: both } span.align-center>span { display: block; overflow: hidden; margin: 13px auto 0; text-align: center } span.align-center span img { margin: 0 auto; text-align: center } span.align-right { display: block; overflow: hidden; clear: both } span.align-right>span { display: block; overflow: hidden; margin: 13px 0 0; text-align: right } span.align-right span img { margin: 0; text-align: right } span.float-left { display: block; margin-right: 13px; overflow: hidden; float: left } span.float-left span { margin: 13px 0 0 } span.float-right { display: block; margin-left: 13px; overflow: hidden; float: right } span.float-right>span { display: block; overflow: hidden; margin: 13px auto 0; text-align: right } code,tt { margin: 0 2px; padding: 0 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8 } pre code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent } .highlight pre { background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px } pre { background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px } pre code,pre tt { background-color: transparent; border: none } sup { font-size: 0.83em; vertical-align: super; line-height: 0 } kbd { display: inline-block; padding: 3px 5px; font-size: 11px; line-height: 10px; color: #555; vertical-align: middle; background-color: #fcfcfc; border: solid 1px #ccc; border-bottom-color: #bbb } * { }</style> <style>code[class*="language-"],pre[class*="language-"] { color: black; background: none; font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; text-align: left; white-space: pre; word-spacing: normal; line-height: 1.5 } pre[class*="language-"] { position: relative; margin: .5em 0; border-left: 10px solid #358ccb; background-color: #fdfdfd; background-image: linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%); overflow: visible; padding: 0 } code[class*="language"] { max-height: inherit; height: 100%; padding: 0 1em; display: block; overflow: auto } :not(pre)>code[class*="language-"],pre[class*="language-"] { background-color: #fdfdfd; margin-bottom: 1em } :not(pre)>code[class*="language-"] { position: relative; padding: .2em; color: #c92c2c; border: 1px solid rgba(0, 0, 0, 0.1); display: inline; white-space: normal } pre[class*="language-"]::before,pre[class*="language-"]::after { content: ""; z-index: -2; display: block; position: absolute; bottom: 0.75em; left: 0.18em; width: 40%; height: 20%; max-height: 13em } :not(pre)>code[class*="language-"]::after,pre[class*="language-"]::after { right: 0.75em; left: auto } .token.comment,.token.block-comment,.token.prolog,.token.doctype,.token.cdata { color: #7D8B99 } .token.punctuation { color: #5F6364 } .token.property,.token.tag,.token.boolean,.token.number,.token.function-name,.token.constant,.token.symbol,.token.deleted { color: #c92c2c } .token.selector,.token.attr-name,.token.string,.token.char,.token.function,.token.builtin,.token.inserted { color: #2f9c0a } .token.operator,.token.entity,.token.url,.token.variable { color: #a67f59; background: rgba(255, 255, 255, 0.5) } .token.atrule,.token.attr-value,.token.keyword,.token.class-name { color: #1990b8 } .token.regex,.token.important { color: #e90 } .language-css .token.string,.style .token.string { color: #a67f59; background: rgba(255, 255, 255, 0.5) } .token.important { font-weight: normal } .token.bold { font-weight: bold } .token.italic { font-style: italic } .token.entity { cursor: help } .namespace { opacity: .7 } .token.tab:not(:empty)::before,.token.cr::before,.token.lf::before { color: #e0d7d1 } pre[class*="language-"].line-numbers { padding-left: 0 } pre[class*="language-"].line-numbers code { padding-left: 3.8em } pre[class*="language-"].line-numbers .line-numbers-rows { left: 0 } pre[class*="language-"][data-line] { padding-top: 0; padding-bottom: 0; padding-left: 0 } pre[data-line] code { position: relative; padding-left: 4em } pre .line-highlight { margin-top: 0 }</style> <style>pre.line-numbers { position: relative; padding-left: 3.8em; counter-reset: linenumber } pre.line-numbers>code { position: relative } .line-numbers .line-numbers-rows { position: absolute; top: 0; font-size: 100%; left: -3.8em; width: 3em; letter-spacing: -1px; border-right: 1px solid #999 } .line-numbers-rows>span { display: block; counter-increment: linenumber } .line-numbers-rows>span::before { content: counter(linenumber); color: #999; display: block; padding-right: 0.8em; text-align: right }</style> <style>div.prism-show-language { position: relative } div.prism-show-language>div.prism-show-language-label { color: black; background-color: #CFCFCF; display: inline-block; position: absolute; bottom: auto; left: auto; top: 0; right: 0; width: auto; height: auto; font-size: 0.9em; padding: 0 0.5em; z-index: 1 }</style>-
思维导图
-
详情
UDID
在之前的版本是可以被使用的,iOS5及以后,被苹果禁止使用了(弃用了)。虽然,这个UDID用得很广泛,但是,不得不说的是,它在慢慢的远离开发者,不能在考虑使用UDID了。至于这个标示符是转为私有方法,或者完全从以后的iOS版本中移除,还有待观察。不过,这个UDID在部署企业级签名程序时,非常方便。
获取UDID的方法如下: NSString *udid = [[UIDevice currentDevice] uniqueIdentifier];
示例:bb4d786633053a0b9c0da20d54ea7e38e8776da4
OpenUDID(github上一个开源的项目)
在iOS 5发布时,UDID被弃用了,这引起了广大开发者需要寻找一个可以替代UDID,并且不受苹果控制的方案。由此OpenUDID成为了当时使用最广泛的开源UDID替代方案。OpenUDID在工程中实现起来非常简单,并且还支持一系列的广告提供商。
获取UDID的方法如下: NSString *openUDID = [OpenUDID value];
OpenUDID原理是利用iOS系统中的UIPasteboard剪贴板类,它用 app-special pastboards 来存储一160位的随机字符串,存取的方式类似字典的key-value。 app-special pastboards 可持久存储字符串,即使开关机、卸载应用,并能在app之间共享。Openudid的第一次访问的时候用key去检查剪贴板内是否存在对应的value(随机数),如果不存在就生成一个并存储在Pasteboard中,第二次访问的时候就可以直接取到而不去生成新的随机数。 但是iOS7之后,苹果封堵了剪贴板通信的漏洞,iOS之前是所有的应用都可以共享同一个剪贴板存储内容,现在只有在同一CFBundleIdentifier标识下的App才能共享内容,如com.koudai.a和com.koudai.b,它们的com.mycompany部分是一样的,就能共享(请用真机测试,模拟器会有偏差)。
UUID
目前大部分应用存的是UUID,它是苹果再iOS6后提供的一个获取大随机数的方法。UUID, 全球独立标识(Globally Unique Identifier),据wiki说UUID随机数算法得到的数重复概率为170亿分之一,170亿分之一什么概念?可以告诉你买一注双色球的中奖概率是1700万分之一。
以下是几种取到UUID的方法,它们各有区别:
CFUUID
从iOS2.0开始,CFUUID就已经出现了。它是CoreFoundatio包的一部分,因此API属于C语言风格。CFUUIDCreate 方法用来创建CFUUIDRef,并且可以获得一个相应的NSString。获得的这个CFUUID值系统并没有存储。每次调用CFUUIDCreate,系统都会返回一个新的唯一标示符。如果你希望存储这个标示符,那么需要自己将其存储到NSUserDefaults, Keychain, Pasteboard或其它地方。
获取CFUUID方法如下: CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault);NSString *cfuuidString = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));
示例:68753A44-4D6F-1226-9C60-0050E4C00067
NSUUID
NSUUID在iOS 6中才出现,这跟CFUUID几乎完全一样,只不过它是Objective-C接口。跟CFUUID一样,这个值系统也不会存储,每次调用的时候都会获得一个新的唯一标示符。如果要存储的话,你需要自己存储。
获取NSUUID方法如下:NSString *uuid = [[NSUUID UUID] UUIDString];
示例:68753A44-4D6F-1226-9C60-0050E4C00067
IDFA-identifierForIdentifier
这是iOS 6中另外一个新的方法,advertisingIdentifier是新框架AdSupport.framework的一部分。ASIdentifierManager单例提供了一个方法advertisingIdentifier,通过调用该方法会返回一个上面提到的NSUUID实例。
跟CFUUID和NSUUID不一样,广告标示符是由系统存储着的。不过即使这是由系统存储的,但是有几种情况下,会重新生成广告标示符。如果用户完全重置系统((设置程序 -> 通用 -> 还原 -> 还原位置与隐私) ,这个广告标示符会重新生成。另外如果用户明确的还原广告(设置程序-> 通用 -> 关于本机 -> 广告 -> 还原广告标示符) ,那么广告标示符也会重新生成。关于广告标示符的还原,有一点需要注意:如果程序在后台运行,此时用户“还原广告标示符”,然后再回到程序中,此时获取广告标示符并不会立即获得还原后的标示符。必须要终止程序,然后再重新启动程序,才能获得还原后的广告标示符。之所以会这样,我猜测是由于ASIdentifierManager是一个单例。
针对广告标示符用户有一个可控的开关“限制广告跟踪”。Nick Arnott的文章中已经指出了。将这个开关打开,实际上什么也没有做,不过这是希望限制你访问广告标示符。这个开关是一个简单的boolean标志,当将广告标示符发到任意的服务器端时,你最好判断一下这个值,然后再做决定。
注意:Appstore禁止不使用广告而采集IDFA的app上架。请参考
获取IDFA方法如下:NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
示例:E2DFA89-496A-47FD-9941-DF1FC4E6484A
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.意思是根据vendor的值,如果vendor相同,则返回同一字符串;如果vendor不同,则返回不同的字符串。
vendor解释:英文解释为卖家,小贩。根据xcode文档解释,正常情况下,会根据App Store提供的数据进行判断。但是如果app不是通过app store进行安装的(如企业应用或开发调试阶段),那么会根据bundle ID判断。
获取IDFA方法如下:NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
示例:E2DFA89-496A-47FD-9941-DF1FC4E6484A
注:天生的普通人
获取iOS设备唯一标识