首页 > 开发 > iOS > 正文

iOS - 获取设备标识符UUID/UDID/IMEI等

2017-11-07 09:52:07  来源: 网友分享

IDFA: 

广告标示符,它是由系统存储着的,iOS6及以后使用。但是如果用户还原位置与隐私的话这个广告标识符就会重新生成(设置程序 -》 通用 -》 还原 -》还原位置与隐私) 。或者用户更明确的将设置中的广告还原掉(设置程序 -》 通用-》 关于本机 -》广告 -》 还原广告标示符) ,IDFA也会重新生成。而且用户可以在设置-》隐私 -》广告里面限制IDFA获取,一般用户都不知道有这个,哈哈,不过还是不能用来做唯一标识的id呦。

#import <AdSupport/ASIdentifierManager.h>
ASIdentifierManager *asIM = [[ASIdentifierManager alloc] init];
NSString *idfa = [asIM.advertisingIdentifier UUIDString];


IDFV: 

iOS6.0及以后使用,是给Vendor标识用户用的,vendor:卖主,小贩。经过测试发现com.test.app1和com.test.app2具有相同的idfv,而如果是com.app1和com.app2则是两个不同的idfv。准确点说,就是通过BundleID的反转的前两部分进行匹配,如果相同就是同一个Vender,共享同一个idfv的值。

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


IMEI,IMSI: 

IMEI(International Mobile Equipment Identity)是国际移动设备身份码的缩写,国际移动装备辨识码,是由15位数字组成的”电子串号”,它与每台手机一一对应,而且该码是全世界唯一的。每一部手机在组装完成后都将被赋予一个全球唯一的一组号码,这个号码从生产到交付使用都将被制造生产的厂商所记录。手机用户可以在手机中查到自己手机的IMEI码。 

重点来了 !iOS5以后不能再获取了,但通过私有Api能获取,这是在网上能查到的。Git上的erica的UIDevice扩展文件,以前可用但由于IOKit framework没有公开,所以也无法使用。就算手动导入,依旧无法使用,看来获取IMEI要失败了,同时失败的还有IMSI。不过还存在另外一种可能,Stack Overflow上有人提供采用com.apple.coretelephony.Identity.get entitlement方法,but device must be jailbroken;在此附上链接,供大家参考:http://stackoverflow.com/questions/16667988/how-to-get-imei-on-iphone-5/16677043#16677043 

如果实现了,自己拿来玩就行,别上架,这是会被拒掉的。


Mac地址,这个是做IDFA的时候,从友盟收集到的方法: 

要导入一堆头文件:


#include <sys/sysctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_dl.h>
    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");
        free(buf);
        return NULL;
    }
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    NSString *macStr = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",*ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    free(buf);

UDID 

只能说搜遍了每个地方,获取UDID的方法真难找到,炸了!不过Stack Overflow上提供了一种获取方法,越狱可尝试:http://stackoverflow.com/questions/27602368/how-to-get-serial-number-of-a-device-using-iokit-in-ios8-as-ioplatformserialnumb/27686125#27686125 

。UDID的唯一性使得许多开发者可以从多个应用收集用户的许多隐私数据。这是苹果不允许的,在iOS 5 的时候,废除掉相关信息。现在应用试图获取UDID被禁止且不允许上架。

UUID ,获取唯一标识符


每次运行都会发生变化,最理想的就是保存在keychain里面,以此作为标识用户设备的唯一标识符


CFUUIDRef uuid = CFUUIDCreate(NULL);
    assert(uuid != NULL);
    CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid);
    DYLog(@"uuidStr------》%@",uuidStr);


之前使用了Git上的一个第三方库,SSKeychain,将UUID保存在keychain里面,每次调用先检查钥匙串里面有没有,有则使用,没有则写进去,保证其唯一性,具体使用如下:


CFUUIDRef uuid = CFUUIDCreate(NULL);
assert(uuid != NULL);
CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid);
NSString *identifierNumber = [SSKeychain passwordForService:@"com.test.app1"account:@"user"];
if (!identifierNumber){
   [SSKeychain setPassword: [NSString stringWithFormat:@"%@", uuidStr] forService:@"com.test.app1"account:@"user"];
   identifierNumber = [SSKeychain passwordForService:@"com.test.app1"account:@"user"];
}