iOS获取设备唯一标识

IDFA(广告标识)

IDFA只支持iOS 6以上

+(NSString *)idfa
{
    //这里最好随机生成一个值,在iOS6以上用户关闭获取广告追踪也会造成idfa无法获取
    NSString *ad = @"iOS5WithoutIDFA";
    if ([[[UIDevice  currentDevice] systemVersion] intValue]>=6) {
        ad= [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
    }
    return ad;
}

IDFV(推广标识)

IDFA作为推广id,只适用于同Vender下获取到的值相同。即同一个厂商发布的应用

+(NSString *)idfv
{
    NSString *ad = @"iOS5WithoutIDFV";
    if ([[[UIDevice  currentDevice] systemVersion] intValue]>=6) {
        ad= [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    }
    return ad;
}

在UUID被苹果禁用以后,可以用IDFA作为设备的唯一标识。由于IDFA在设置中可以被用户修改或关闭获取权限,一般配合钥匙串(Keychain)使用。

需要添加的系统库
#import 
存入钥匙串
+ (void)save:(NSString *)service data:(id)data {
    //Get search dictionary
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    //Delete old item before add new item
    SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
    //Add new object to search dictionary(Attention:the data format)
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
    //Add item to keychain with the search dictionary
    SecItemAdd((__bridge 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:(__bridge id)kSecReturnData];
    [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
    CFDataRef keyData = NULL;
    if (SecItemCopyMatching((__bridge 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;
}
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
    return [NSMutableDictionary dictionaryWithObjectsAndKeys:
            (__bridge id)kSecClassGenericPassword,(__bridge id)kSecClass,
            service, (__bridge id)kSecAttrService,
            service, (__bridge id)kSecAttrAccount,
            (__bridge id)kSecAttrAccessibleAfterFirstUnlock,(__bridge id)kSecAttrAccessible,
            nil];
}

最终获取设备唯一标识的方法

+(NSString *)getUniqueIdentifier
{
    NSMutableDictionary *idfvKVPairs = (NSMutableDictionary *)[LKIADKeychain load:RK_KEY_DEVICE_IDENTIFIER_PASSWORD];
    NSString *ad = [idfvKVPairs objectForKey:RK_KEY_IDENTIFIER];
    if ([ad length]<3) {
        idfvKVPairs = [NSMutableDictionary dictionary];
        ad = [LKIADDDeviceIdentifier idfa];
        if ([ad length]<3) {
            ad  = [self createUUID];
        }
        [idfvKVPairs setObject:ad forKey:RK_KEY_IDENTIFIER];
        [LKIADKeychain save:RK_KEY_DEVICE_IDENTIFIER_PASSWORD data:idfvKVPairs];
    }
    return ad;
}

在其他设备中常用作为唯一标识的mac地址也不适用iOS,在iOS7以上的设备中获取到的是固定值 02:00:00:00:00:00

mac地址获取方法
+(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)];
    free(buf);
    NSString *mac= [outstring uppercaseString];
    return mac;
}

你可能感兴趣的:(iOS获取设备唯一标识)