iOS获取手机唯一标识符来判断不同终端登录(IDFA和UUID分析)

11.13更新

广告标示符,适用于对外:例如广告推广,换量等跨应用的用户追踪等。

是iOS 6中另外一个新的方法,提供了一个方法advertisingIdentifier,通过调用该方法会返回一个NSUUID实例,最后可以获得一个UUID,由系统存储着的。不过即使这是由系统存储的,但是有几种情况下,会重新生成广告标示符。如果用户完全重置系统((设置程序 -> 通用 -> 还原 -> 还原位置与隐私) ,这个广告标示符会重新生成。另外如果用户明确的还原广告(设置程序-> 通用 -> 关于本机 -> 广告 -> 还原广告标示符) ,那么广告标示符也会重新生成。关于广告标示符的还原,有一点需要注意:如果程序在后台运行,此时用户“还原广告标示符”,然后再回到程序中,此时获取广 告标示符并不会立即获得还原后的标示符。必须要终止程序,然后再重新启动程序,才能获得还原后的广告标示符。

在同一个设备上的所有App都会取到相同的值,是苹果专门给各广告提供商用来追踪用户而设的,用户可以在 设置|隐私|广告追踪 里重置此id的值,或限制此id的使用,故此id有可能会取不到值,但好在Apple默认是允许追踪的,而且一般用户都不知道有这么个设置,所以基本上用来监测推广效果,是戳戳有余了。

注意:由于idfa会出现取不到的情况,故绝不可以作为业务分析的主id,来识别用户。
因此,IDFA就是用来跟踪广告推广的,而UUID虽然每次不同,但是可以自己手动存入Keychain来进行唯一性的确保,这么说来IDFA就是如果广告商投放的时候使用,而UUID就是自己后台来判断用户是否换了设备,或者信息不一致需要重新登录的业务
知乎上看到一个非常详细介绍IDFA的文章
IDFA看这个就够了

IDFA

可以理解为广告id,apple公司提供的用于追踪用户的广告标识符。缺点:如果用户完全重置系统((设置程序 -> 通用 -> 还原 -> 还原位置与隐私) ,这个广告标示符会重新生成。
另外如果用户明确的还原广告(设置程序-> 通用 -> 关于本机 -> 广告 -> 还原广告标示符) ,那么广告标示符也会重新生成

这是iOS 6中另外一个新的方法,advertisingIdentifier是新框架AdSupport.framework的一部分。ASIdentifierManager单例提供了一个方法advertisingIdentifier,通过调用该方法会返回一个上面提到的NSUUID实例。

// 获取
//需要导入AdSupport.framework这个库
#import 
NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

// 判断是否开启
// 判断是否开启  限制广告跟踪选项(该选项在设置-隐私-广告-限制广告隐私)
Boolean on = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];

ios10之前开关限制广告追踪选项的确没什么用,ios10之后,如果手机开启限制广告追踪的话就不能再得到广告标识符,得到的是下面的0。这个开关是一个简单的boolean标志,当将广告标示符发到任意的服务器端时,你最好判断一下这个值,然后再做决定。

//开启的时候
2016-01-05 15:22:19.218 sss[1773:60b] 41B2FD07-695A-4A27-8D26-C30ECE6F7EAD
2016-01-05 15:22:19.233 sss[1773:60b] 0

//关闭的时候
2016-01-05 15:19:57.502 sss[1763:60b] 7773E145-26FF-4304-A60F-60C948D52B40
2016-01-05 15:19:57.516 sss[1763:60b] 1

开启和关闭切换的话,idfa会变,如果不切换,保持开启状态,每次都是不会变的,当切换了下之后就会变,或者还原的话会变

// 获取IDFA的方法
+ (NSString *)getIDFA
{
    SEL advertisingIdentifierSel = sel_registerName("advertisingIdentifier");
    SEL UUIDStringSel = sel_registerName("UUIDString");

    ASIdentifierManager *manager = [ASIdentifierManager sharedManager];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    if([manager respondsToSelector:advertisingIdentifierSel]) {

        id UUID = [manager performSelector:advertisingIdentifierSel];

        if([UUID respondsToSelector:UUIDStringSel]) {

            return [UUID performSelector:UUIDStringSel];

        }

    }
#pragma clang diagnostic pop
    return nil;
}

UUID

CFUUID—>2.0出现
NSUUID—>6.0出现
这两个一个是CF框架下的,一个更加面向对象,获取的时候更方便而已,其实获取到的都是同一个东西
针对CFUUID需要注意的是:获得的这个CFUUID值系统并没有存储。每次调用CFUUIDCreate,系统都会返回一个新的唯一标示符。如果你希望存储这个标示符,那么需要自己将其存储到NSUserDefaults, Keychain, Pasteboard或其它地方。

由于我们后台判断App登录时根据uuid来判断的在不同终端登录的,虽然上面提到UUID是获取的时候一直在变化的,而且不是系统级别的存储,那么我们就需要自己存储到系统,用到SSKeyChain,我们自己来保证一个手机理论状态下对应一个UUID

+ (NSString *)getUUID{
    NSString  *openUUID = [[NSUserDefaults standardUserDefaults] objectForKey:OpenSessionID];
//    NSLog(@"openUUID 一: %@",openUUID);
    if (openUUID == nil) {

        CFUUIDRef puuid = CFUUIDCreate(kCFAllocatorDefault);
        CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault,puuid);
        NSString *udidStr = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString));
        CFRelease(puuid);
        CFRelease(uuidString);
        openUUID =  [udidStr MD5Hash];

//        NSLog(@"openUUID 二: %@",openUUID);
        NSString *uniqueKeyItem = [SSKeychain  passwordForService:kUniqueIdentifier account:kUniqueIdentifierValue];
        if (uniqueKeyItem == nil || [uniqueKeyItem length] == 0) {
            uniqueKeyItem = openUUID;
            [SSKeychain  setPassword:openUUID forService:kUniqueIdentifier account:kUniqueIdentifierValue];
        }
        [[NSUserDefaults standardUserDefaults] setObject:uniqueKeyItem forKey:OpenSessionID];
        [[NSUserDefaults  standardUserDefaults] synchronize];
//        NSLog(@"uniqueKeyItem: %@",uniqueKeyItem);
        openUUID = uniqueKeyItem;
    }
//    NSLog(@"openUUID 三: %@",openUUID);
    return openUUID;
}

1.首先从沙盒获取,没有的话就调用CF方法获取,然后再去keychain获取,如果没获取到,把刚才获取到的UUID存储到Keychain,由于keychain你不刷机,存储的东西会一直存在,因此保证了唯一性,每次获取的都是从keychain获取到的第一次存储进去的值,那么请求的时候,后台根据用户主键盘点uuid是否更改从而判断是否换了终端登录,进行弹框提示

iOS获取手机唯一标识符来判断不同终端登录(IDFA和UUID分析)_第1张图片
iOS获取手机唯一标识符来判断不同终端登录(IDFA和UUID分析)_第2张图片

总结:
1.idfa在用户重置广告标志符的时候会变化,所以可以把第一次生成的idfa存放到keychain里面,以后就直接读取keychain值就可以了,这样就能避免用户重置广告标志符造成idfa的变化,而keychain的值只有在用户重置系统的时候才会删除,所以很适合用idfa+keychain的方案
2.那么第二种方法也可以用,UUID+Keychain的方式也行,上面介绍了,我们就用的第二种,总之,keychain是个好东西,根据app的键,来存储对应的用户信息,密码等重要信息还是不错的,这里简单记录下之前一直疑惑的知识点,方便以后查阅

IDFA提交Appstore选项相关

如何确定是否需要选择IDFA???先看看下面的终端使用判断是否需要勾选
iOS审核中如何正确填写APP广告标识符IDFA

1、在 App 内投放广告

2、将此 App 安装归因于先前投放的特定广告

3、将此 App 中发生的操作归因于先前投放的特定广告

4、对使用广告标识符做确认

1.serve advertisements within the app

服务应用中的广告。如果你的应用中集成了广告的时候,你需要勾选这一项。

2.Attribute this app installation to a previously served advertisement.

跟踪广告带来的安装。如果你使用了第三方的工具来跟踪广告带来的激活以及一些其他事件,但是应用里并没有展示广告你需要勾选这一项。

3.Attribute an action taken within this app to a previously served advertisement

跟踪广告带来的用户的后续行为。如果你使用了第三方的工具来跟踪广告带来的激活以及一些其他事件,但是应用里并没有展示广告你需要勾选第2项和第3项。

下边还有一项

4.Limit Ad Tracking setting in iOS

这一项下的内容其实就是对你的应用使用idfa的目的做下确认,只要你选择了采集idfa,那么这一项都是需要勾选的。

总结一下,

(1)如果你的应用里只是集成了广告,不追踪广告带来的激活行为,那么选择1和4;

(2)如果你的应用里没有集成广告,但是需要追踪广告带来的激活行为,那么选择2,3和4;

(3)如果你的应用里集成了广告,而且使用了sdk等用来追踪广告带来的激活行为,需要选择1,2,3和4 。

个人理解:当你有用到IDFA的时候,你是必须要勾选YES的,14年的时候很严格,剩下四个选项如果你选错了很容易悲剧,现在感觉如果你选了YES,然后在找个合适的理由勾选,基本上没问题了,例如你集成了UMENG的IDFA SDK,然后你有启动广告,你选1和4,一样OK了

参考博客,还介绍了其他标识符

你可能感兴趣的:(iOS获取手机唯一标识符来判断不同终端登录(IDFA和UUID分析))