iOS获取设备ID总结

作者: 秦明Qinmin | 来源:发表于2016-04-09 15:59 被阅读16062次

    iOS获取设备ID总结

    UDID

    简介:UDID的全称是Unique Device Identifier,顾名思义,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和数字组成。在很多需要限制一台设备一个账号的应用中经常会用到。在iOS5中可以获取到设备的UDID,iOS7中已经完全的禁用了它。iOS7之前的使用了的app如果在iOS7上运行,它不会返回设备的UDID,而是会返回一串字符串,以FFFFFFFF开头,跟着identifierForVendor的十六进制值。

    获取:[[UIDevice currentDevice] uniqueIdentifier]

    废弃:iOS6

    IDFV

    简介:iOS 6.0系统新增用于替换uniqueIdentifier的接口。是给Vendor标识用户用的,每个设备在所属同一个Vender的应用里,都有相同的值。其中的Vender是指应用提供商,但准确点说,是通过BundleID的DNS反转的前两部分进行匹配,如果相同就是同一个Vender,例如对于com.somecompany.appone,com.somecompany.apptwo这两个BundleID来说,就属于同一个Vender,共享同一个idfv的值。和idfa不同的是,idfv的值是一定能取到的,所以非常适合于作为内部用户行为分析的主id,来标识用户,替代OpenUDID。如果用户将属于此Vender的所有App卸载,则idfv的值会被重置,即再重装此Vender的App,idfv的值和之前不同。

    获取:[[[UIDevice currentDevice] identifierForVendor] UUIDString]

    适用:iOS6.0+

    例子:95955F33-BFBD-48BA-A630-866D2DAE482D

    IDFA

    简介:广告标示符,适用于对外:例如广告推广,换量等跨应用的用户追踪等。但如果用户完全重置系统((设置程序 -> 通用 -> 还原 -> 还原位置与隐私) ,这个广告标示符会重新生成。另外如果用户明确的还原广告(设置程序-> 通用 -> 关于本机 -> 广告 -> 还原广告标示符) ,那么广告标示符也会重新生成。注意:如果程序在后台运行,此时用户“还原广告标示符”,然后再回到程序中,此时获取广 告标示符并不会立即获得还原后的标示符。必须要终止程序,然后再重新启动程序,才能获得还原后的广告标示符。在同一个设备上的所有App都会取到相同的值,是苹果专门给各广告提供商用来追踪用户而设的,用户可以在 设置 -> 隐私 -> 广告追踪 里重置此id的值,或限制此id的使用。

    获取:[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

    适用:iOS6.0+

    例子:9C287922-EE26-4501-94B5-DDE6F83E1475

    MAC地址

    简介:MAC地址在网络上用来区分设备的唯一性,接入网络的设备都有一个MAC地址,他们肯定都是不同的,是唯一的。一部iPhone上可能有多个MAC地址,包括WIFI的、SIM的等,但是iTouch和iPad上就有一个WIFI的,因此只需获取WIFI的MAC地址就好了,也就是en0的地址。MAC地址就如同我们身份证上的身份证号码,具有全球唯一性。但在iOS7之后,如果请求Mac地址都会返回一个固定值。

    废弃:iOS7.0+

    获取:

    - (NSString *)macAddress  
    {  
          
        int                 mib[6];  
        size_t              len;  
        char                *buf;  
        unsigned char       *ptr;  
        struct if_msghdr    *ifm;  
        struct sockaddr_dl  *sdl;  
          
        mib[0] = CTL_NET;  
        mib[1] = AF_ROUTE;  
        mib[2] = 0;  
        mib[3] = AF_LINK;  
        mib[4] = NET_RT_IFLIST;  
          
        if ((mib[5] = if_nametoindex("en0")) == 0) {  
            printf("Error: if_nametoindex error/n");  
            return NULL;  
        }  
          
        if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {  
            printf("Error: sysctl, take 1/n");  
            return NULL;  
        }  
          
        if ((buf = malloc(len)) == NULL) {  
            printf("Could not allocate memory. error!/n");  
            return NULL;  
        }  
          
        if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {  
            printf("Error: sysctl, take 2");  
            return NULL;  
        }  
          
        ifm = (struct if_msghdr *)buf;  
        sdl = (struct sockaddr_dl *)(ifm + 1);  
        ptr = (unsigned char *)LLADDR(sdl);  
        NSString *outstring = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];  
          
        NSLog(@"outString:%@", outstring);  
          
        free(buf);  
          
        return [outstring uppercaseString];  
    }
    

    KeyChain

    简介:iOS整个系统有一个KeyChain,每个程序都可以往KeyChain中记录数据,而且只能读取到自己程序记录在KeyChain中的数据。而且就算我们程序删除掉,系统经过升级以后再安装回来,依旧可以获取到与之前一致的UDID(系统还原、刷机除外)。因此我们可以将UUID的字符串存储到KeyChain中,然后下次直接从KeyChain获取UUID字符串。(本示例中使用KeychainItemWrapper工具类)

    获取:

    + (NSString *)UUID {
        KeychainItemWrapper *keyChainWrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MYAppID" accessGroup:@"com.test.app"];
        NSString *UUID = [keyChainWrapper objectForKey:(__bridge id)kSecValueData];
        
        if (UUID == nil || UUID.length == 0) {
            UUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
            [keyChainWrapper setObject:UUID forKey:(__bridge id)kSecValueData];
        }
        
        return UUID;
    }
    

    AppleAccount

    简介:虽然苹果在iOS6中禁用了获取uuid的方式,但是只要你研究下就知道这个API只是私有化了,使用私有API还是可以获取设备的uuid。但是这个方面也面临着风险:比如API变更以及AppStore审核问题,但是在越狱设备上你还是可以尽情享用的。

    类:AADeviceInfo(dump出头文件)

    @class NSObject<OS_dispatch_semaphore>, APSConnection, NSData;
    
    @interface AADeviceInfo : NSObject {
    
    APSConnection *_apsConnection;
    
    BOOL _tokenDone;
    
    NSData *_token;
    
    NSObject<OS_dispatch_semaphore> *_tokenSema;
    
    }
    
    + (id)userAgentHeader;
    
    + (id)signatureWithDictionary:(id)arg1;
    
    + (id)apnsToken;
    
    + (id)serialNumber;
    
    + (id)clientInfoHeader;
    
    + (id)appleIDClientIdentifier;
    
    + (id)productVersion;
    
    + (id)osVersion;
    
    + (id)udid;
    
    + (id)infoDictionary;
    
    - (id)wifiMacAddress;
    
    - (id)regionCode;
    
    - (id)deviceClass;
    
    - (id)osName;
    
    - (id)productType;
    
    - (id)apnsToken;
    
    - (id)serialNumber;
    
    - (id)deviceInfoDictionary;
    
    - (id)appleIDClientIdentifier;
    
    - (id)productVersion;
    
    - (id)osVersion;
    
    - (id)udid;
    
    - (id)init;
    
    - (void).cxx_destruct;
    
    - (id)buildVersion;
    
    @end
    

    获取:[AADeviceInfo udid]

    使用方法:在项目中将真机上的AppleAccount.framework框架导出,引入Xcode工程中,利用runtime或者直接使用该类就行。(细节补充:导出AppleAccount.framework后,进入AppleAccount.framework的根目录,新建Headers文件夹,然后将dump出的头文件放在Headers目录,就可以像引用第三方framework一样在项目中使用)

    相关文章

      网友评论

      • f4ce6eb6e4fc:AppleAccount.framework框架导出 的问题。 从哪里找到并导出。
        求这个教程。
      • 秦明Qinmin:UDID的全称是Unique Device Identifier,设备的唯一识别码(机器的特性)。UUID(Universally Unique Identifier)全局唯一标识符,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的(生成的)。
      • FengxinLi:请问一下楼主 UDID 和UUID 是一样吗?看你前面写的UDID,后面写的UUID
        焱止殇:@Fengxinliju 不一样,UUID重启手机之后会改变,所以楼主说的解决办法是钥匙串+UUID的存储方式替代UDID

      本文标题:iOS获取设备ID总结

      本文链接:https://www.haomeiwen.com/subject/qkcblttx.html