zoukankan      html  css  js  c++  java
  • 获取UIDevice的uniqueIdentifier替代方法

    iOS5之后,原来获取iPhone的DeviceId的接口:[UIDevice uniqueIdentifier] 被废弃!

    这个改动会影响非常多的人,尤其是数据分析者。由于iPhone取IMEI困难(属于私有方法),所以大多数应用将DeviceId,也就是uniqueIdentifier作为IMEI来使用。如果这个接口被废弃,那么,我们就需要寻求一个新的方式来标识唯一的设备。

    官方推荐的方法是,每个应用内创建一个UUID来作为唯一标志,并将之存储,但是这个解决方法明显不能接受!原因是,你每次创建的UUID都是不一样的,意味着,你卸载后重新安装这个软件,生成的UUID就不一样了,无法达到我们将之作为数据分析的唯一标识符的要求。

    现有的解决方案是,使用iPhone的Mac地址,因为Mac地址也是唯一的。unix有系统调用可以获取Mac地址。但是有些事情需要注意:

    1.iPhone可能有多个Mac地址,wifi的地址,以及SIM卡的地址。一般来讲,我们取en0的地址,因为他是iPhone的wifi的地址,是肯定存在的。(例外情况依然有:市面上依然存在一部分联通的阉割版无wifi的iPhone)

    2.Mac地址涉及到隐私,不应该胡乱将用户的Mac地址传播!所以我们需要将Mac地址进行hash之后,才能作为DeviceId上传。

    网上已经有现成的解决方案:

    https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5

    以下是一份大致类似的方案

    1.通过调用CFFUUIDCreate函数来生成机器唯一标识符,但每次调用以下函数返回的字符串都不一样,所以第一次调用后需把该字符串存储起来。这是官方API的建议方法

    - (NSString *) uniqueString

    {

    CFUUIDRef unique = CFUUIDCreate(kCFAllocatorDefault);

    NSString *result = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, unique) autorelease];

    CFRelease(unique);

    return result;

    }

    2.由于机器的mac地址都不一样,所以可通过获取mac地址后再进行md5加密处理后返回的字符串作为唯一标识码

    - (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, 6NULL, &len, NULL0) < 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, NULL0) < 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);

        

        return outstring;

    }

    - (NSString *) uniqueGlobalDeviceIdentifier{

        NSString *macaddress = [[UIDevice currentDevicemacaddress];

        NSString *uniqueIdentifier = [macaddress stringFromMD5];

        

        return uniqueIdentifier;

    }

    NSString类别

    @implementation NSString(MD5Addition)

    - (NSString *) stringFromMD5{

        

        if(self == nil || [self length] == 0)

            return nil;

        

        const char *value = [self UTF8String];

        

        unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];

        CC_MD5(value, strlen(value), outputBuffer);

        

        NSMutableString *outputString = [[NSMutableString allocinitWithCapacity:CC_MD5_DIGEST_LENGTH * 2];

        for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){

            [outputString appendFormat:@"%02x",outputBuffer[count]];

        }

        

        return [outputString autorelease];

    }

  • 相关阅读:
    Java学习---Java代码编写规范
    移动端与Web端疫情数据展示
    Java实现邮箱验证码
    Java实现短信验证码
    利用Jsoup爬取新冠疫情数据并存至数据库
    echarts全国疫情统计可视化地图(第一阶段)
    构建之法阅读笔记04
    HDU 4628 Pieces(状压DP)题解
    ZOJ 2563 Long Dominoes(状压DP)题解
    POJ 2288 Islands and Bridges(状压DP)题解
  • 原文地址:https://www.cnblogs.com/edgarli/p/2860614.html
Copyright © 2011-2022 走看看