8种iOS获取设备唯一标识的方法,希望对大家有用。
UDID
UDID(Unique Device Identifier),iOS 设备的唯一识别码,是一个40位十六进制序列(越狱的设备通过某些工具可以改变设备的 UDID),移动网络可以利用 UDID 来识别移动设备。
许多开发者把 UDID 跟用户的真实姓名、密码、住址、其它数据关联起来,网络窥探者会从多个应用收集这些数据,然后顺藤摸瓜得到这个人的许多隐私数据,同时大部分应用确实在频繁传输 UDID 和私人信息。 为了避免集体诉讼,苹果最终决定在 iOS 5 的时候,将这一惯例废除。
现在应用试图获取 UDID 已被禁止且不允许上架。
MAC 地址
MAC(Medium / Media Access Control)地址,用来表示互联网上每一个站点的标示符,是一个六个字节(48位)的十六进制序列。前三个字节是由 IEEE 的注册管理机构 RA 负责给不同厂家分配的”编制上唯一的标示符(Organizationally Unique Identifier)”,后三个字节由各厂家自行指派给生产的适配器接口,称为扩展标示符。
MAC 地址在网络上用来区分设备的唯一性,接入网络的设备都有一个MAC地址,他们肯定都是唯一的。一部 iPhone 上可能有多个 MAC 地址,包括 WIFI 的、SIM 的等,但是 iTouch 和 iPad 上就有一个 WIFI 的,因此只需获取 WIFI 的 MAC 地址就好了。一般会采取 MD5(MAC 地址 + bundleID)获取唯一标识。
但是 MAC 地址和 UDID 一样,存在隐私问题, iOS 7 之后,所有设备请求 MAC 地址会返回一个固定值,这个方法也不攻自破了。
OpenUDID
UDID 被弃用后,广大开发者需要寻找一个可以替代的 UDID,并且不受苹果控制的方案,由此,OpenUDID 成为了当时使用最广泛的开源 UDID 代替方案。OpenUDID 利用一个非常巧妙的方法在不同程序间存储标示符:在粘贴板中用了一个特殊的名称来存储标示符,通过这种方法,其他应用程序也可以获取。
苹果在 iOS 7 之后对粘贴板做了限制,导致同一个设备上的应用间,无法再共享一个 OpenUDID。
UUID + 自己存储
UUID(Universally Unique IDentifier),通用唯一标示符,是一个32位的十六进制序列,使用小横线来连接:8-4-4-4-12,通过 NSUUID(iOS 6 之后)[NSUUID UUID].UUIDString 或者 CFUUID(iOS 2 之后) CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, CFUUIDCreate(kCFAllocatorDefault))) 来获取,但是每次获取的值都不一样,需要自己存储。
推送 token + bundleID
推送 token 保证设备唯一,但是必须有网络情况下才能工作,该方法不依赖于设备本身,但依赖于 apple push,而 apple push 有时候会抽风的。
IDFA
IDFA-identifierForIdentifier(广告标示符),在同一个设备上的所有 APP 都会取到相同的值,是苹果专门给各广告提供商用来追踪用户而设定的。虽然 iPhone 默认是允许追踪的,而且一般用户都不知道有这么个设置,但是用户可以在 设置 - 隐私 - 广告追踪 里重置此 ID 的值,或者限制此 ID 的使用,所以有可能会取不到值。
IDFV
IDFV-identifierForVendor(Vendor 标示符),通过 [UIDevice currentDevice].identifierForVendor.UUIDString 来获取。是通过 bundleID 的反转的前两部分进行匹配,如果相同是同一个 Vendor ,例如对于 com.mayan.app_1 和 com.mayan.app_2 这两个 bundleID 来说,就属于同一个 Vendor ,共享同一个 IDFV,和 IDFA 不同的是,IDFV 的值一定能取到的,所以非常适合于作为内部用户行为分析的主 ID 来识别用户。但是用户删除了该 APP ,则 IDFV 值会被重置,再次安装此 APP ,IDFV 的值和之前的不同。
IDFV + keychain
通过以上几种储存唯一标识的方法的分析,总结一下各有优劣。很多方法被苹果禁止或者漏洞太多,越来越不被开发者使用,现在苹果主推 IDFA 和 IDFV 这两种方法,分别对外和对内,但是 IDFV 在 APP 重新安装时会更改,所以我的方法是通过第一次生成的 IDFV 存储到 keychain 中,以后每次获取标识符都从 keychain 中获取。
#import <UIKit/UIKit.h> @interface MYVendorToll : NSObject + (NSString *)getIDFV; @end
#import "MYVendorToll.h" #import "MYKeyChainTool.h" @implementation MYVendorToll + (NSString *)getIDFV { NSString *IDFV = (NSString *)[MYKeyChainTool load:@"IDFV"]; if ([IDFV isEqualToString:@""] || !IDFV) { IDFV = [UIDevice currentDevice].identifierForVendor.UUIDString; [MYKeyChainTool save:@"IDFV" data:IDFV]; } return IDFV; } @end
#import <Foundation/Foundation.h> @interface MYKeyChainTool : NSObject + (void)save:(NSString *)service data:(id)data; + (id)load:(NSString *)service; + (void)deleteKeyData:(NSString *)service; @end
#import "MYKeyChainTool.h" @implementation MYKeyChainTool + (NSMutableDictionary *)getKeychainQuery:(NSString *)service { return [NSMutableDictionary dictionaryWithObjectsAndKeys: (id)kSecClassGenericPassword,(id)kSecClass, service, (id)kSecAttrService, service, (id)kSecAttrAccount, (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible, nil]; } + (void)save:(NSString *)service data:(id)data { //Get search dictionary NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Delete old item before add new item SecItemDelete((CFDictionaryRef)keychainQuery); //Add new object to search dictionary(Attention:the data format) [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData]; //Add item to keychain with the search dictionary SecItemAdd((CFDictionaryRef)keychainQuery, NULL); } + (id)load:(NSString *)service { id ret = nil; NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Configure the search setting //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; CFDataRef keyData = NULL; if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { @try { ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData]; } @catch (NSException *e) { NSLog(@"Unarchive of %@ failed: %@", service, e); } @finally { } } if (keyData) CFRelease(keyData); return ret; } + (void)deleteKeyData:(NSString *)service { NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; SecItemDelete((CFDictionaryRef)keychainQuery); } @end
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍iOS 获取设备唯一标示符的方法详解,包括了iOS 获取设备唯一标示符的方法详解的使用技巧和注意事项,需要的朋友参考一下 在开发中会遇到应用需要记录设备标示,即使应用卸载后再安装也可重新识别的情况,在这写一种实现方式——读取设备的UUID(Universally Unique Identifier)并通过KeyChain记录。 首先iOS中获取设备唯一标示符的方法一直随版本的更新而变
本文向大家介绍android手机获取唯一标识的方法,包括了android手机获取唯一标识的方法的使用技巧和注意事项,需要的朋友参考一下 获取手机唯一标识 拼接的方式获取手机唯一标识 第一种方式是获取IMEI,但是有的手机如果不是正品的话,就获取不到所以通过这一种方式还是会出现有的设备是没有唯一标识的 第二种方式获取手机卡的序列号,当然这种也不是唯一的,因为有的手机是双卡双待的所以可能会出现空的情况
现在与android 10更新的权限和安全性,我们不能访问用户的设备ID和IMEI号码,但我想要一些设备的唯一ID,以便我们可以跟踪用户。 要求是我们想要/限制一部手机的一次登录
用了nginx代理,本想用IP做标识,但是同一局域网下的所有设备,都是共用同一IP,请问可以获取到局域网ip或者通过哪些参数组合可以区分唯一性
本文向大家介绍超全的iOS各种设备信息获取方法总结(包括iPhone8/iPhone X),包括了超全的iOS各种设备信息获取方法总结(包括iPhone8/iPhone X)的使用技巧和注意事项,需要的朋友参考一下 前言 在开发中,有的时候为了统计用户信息、下发广告,服务器端往往需要手机用户设备及app的各种信息,这些信息的获取可以根据不同的设备或者App、系统版本来提供不同的功能或更好的用户体验
我是新来的。我确实设置了配置,并尝试测试了android kitkat 4.4.2的三星galaxy tab。Appium无法识别设备。该设备被android系统识别,但没有被应用程序识别。请帮助我解决这个问题。 我在这里给出编码 当我运行这个时,Appium显示为0个连接的设备。 但同样配置的Appium在4.3的仿真器中运行良好。