zoukankan      html  css  js  c++  java
  • iOS开发日记20-7.0之后获取设备唯一标识

    今天博主有一个获取设备唯一标识的需求,遇到了一些困难点,在此和大家分享,希望能够共同进步.

    在iOS7.0之前,获取设备唯一标识的方法主要是获取UDID或MAC地址,但是在iOS7.0之后,为了保护用户隐私,苹果把他们都禁止了,使得设备的数据追踪变得越来越难.

    iOS7.0之后,获取设备唯一标识的方法主要有两种:

    1.广告标识符 IDFA

    苹果为了完善自己的生态圈,在2010年前后推出了iAd广告网络。那么这个IDFA和这个iAd的关系就不言自喻了。如果不了解广告也没关系,简单来讲,现在的互联网广告精准投放需要了解用户数据,基于这些信息使得广告更有效率,唯一标识就很重要,就用到了IDFA.

    advertisingIdentifier在AdSupport.framework的ASIdentifierManager类中,是其中两个属性中的一个.

    可以说,用这个IDFA标识设备应该还是很精准的(不然iAd就彻底不用玩了),很多开发者还在使用.

    2.IDFV+Key Chain

    由于IDFV删除app之后再重新安装,标识符就变了,要解决这个问题,可以把第一次生成的ID保存到Key Chain中,删除app之后Key Chain中的数据还在就OK了.

        #define KEY_UDID            @"KEY_UDID"  

        #define KEY_IN_KEYCHAIN     @"KEY_IN_KEYCHAIN"    

        #import <Security/Security.h>  

        #import "APPIdentificationManage.h"  

        @implementation APPIdentificationManage  

        singleton_implementation(APPIdentificationManage)  

        #pragma mark 获取UUID  

        /** 

         *此uuid在相同的一个程序里面-相同的vindor-相同的设备下是不会改变的 

         *此uuid是唯一的,但应用删除再重新安装后会变化,采取的措施是:只获取一次保存在钥匙串中,之后就从钥匙串中获取 

         **/  

        - (NSString *)openUDID  

    {  

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

        return identifierForVendor;  

    }  

        #pragma mark 保存UUID到钥匙串  

        - (void)saveUDID:(NSString *)udid  

    {  

        NSMutableDictionary *udidKVPairs = [NSMutableDictionary dictionary];  

        [udidKVPairs setObject:udid forKey:KEY_UDID];  

        [[APPIdentificationManage sharedAPPIdentificationManage] save:KEY_IN_KEYCHAIN data:udidKVPairs];  

    }  

        #pragma mark 读取UUID  

        /** 

         *先从内存中获取uuid,如果没有再从钥匙串中获取,如果还没有就生成一个新的uuid,并保存到钥匙串中供以后使用 

         **/  

        - (id)readUDID  

    {  

        if (_uuid == nil || _uuid.length == 0) {  

        NSMutableDictionary *udidKVPairs = (NSMutableDictionary *)[[APPIdentificationManage sharedAPPIdentificationManage] load:KEY_IN_KEYCHAIN];    

        NSString *uuid = [udidKVPairs objectForKey:KEY_UDID];  

        if (uuid == nil || uuid.length == 0) {  

        uuid = [self openUDID];  

         [self saveUDID:uuid];  

         }  

          _uuid = uuid;  

       }  

        return _uuid;  

    }  

        #pragma mark 删除UUID  

        - (void)deleteUUID  

    {  

         [APPIdentificationManage delete:KEY_IN_KEYCHAIN];  

    }  

        #pragma mark 查询钥匙串  

        - (NSMutableDictionary *)getKeychainQuery:(NSString *)service {  

        return [NSMutableDictionary dictionaryWithObjectsAndKeys: (__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass,  service, (__bridge_transfer id)kSecAttrService, service,(__bridge_transfer id)kSecAttrAccount,  (__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer id)kSecAttrAccessible,  nil nil];  

    }  

        #pragma mark 将数据保存到钥匙串  

        - (void)save:(NSString *)service data:(id)data {  

        NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  

        SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);  

        [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge_transfer id)kSecValueData];  

        SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);  

    }  

        #pragma mark 加载钥匙串中数据  

        - (id)load:(NSString *)service {  

        id ret = nil;  

        NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  

        [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];  

        [keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];  

        CFDataRef keyData = NULL;  

        if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {  

        @try {  

                ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];  

            } @catch (NSException *e) {  

               NSLog(@"Unarchive of %@ failed: %@", service, e);  

           } @finally {  

           }  

       }  

        return ret;  

    }  

        #pragma mark 删除钥匙串中数据  

        - (void)delete:(NSString *)service {  

        NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  

        SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);  

    }  

    @end  

  • 相关阅读:
    异步编程与scrapy
    统计学 李航读书笔记
    算法模型手写
    《剑指offer》面试题的Python实现
    numpy 中文手册
    django部署
    Django ORM中使用update_or_create功能再解
    RabbitMQ(七)心跳控制 -- heartbeat
    重写__eq__函数——对象list中使用in index()——获得list中不同属性对象个数
    Python机器学习及分析工具:Scikit-learn篇
  • 原文地址:https://www.cnblogs.com/Twisted-Fate/p/4813762.html
Copyright © 2011-2022 走看看