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"]; }