OC(廿二):识别 iOS 设备的唯一性策略--UUID+keyChain存储

KeyChain

iOS的keyChain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keyChain存储。相对于NSUserDefaults、文件保存等一般方式,keyChain保存更为安全,而且keyChain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用,只有刷机或者越狱才对其中的数据有影响.

思路如下:
1,安装 APP 后自动生成一个 UUID
2,检查keyChain中是否有相应关键字的 UUID,如果没有存储,反之不存储.
3,keychain里的数据还能使用,只有刷机或者越狱才对其中的数据有影响.
所以可以很有效保证设备唯一性需求.

代码如下:(封装 keyChain 的方法)
. h

//
//  KeyChainManager.h
//  ChartDemo
//
//  Created by user on 2017/9/27.
//  Copyright © 2017年 MK. All rights reserved.
//

#import 

@interface KeyChainManager : NSObject

+ (NSString *)isExistUUID;

/**
 添加 UUID

 @param uuid 添加的对象
 */
+ (void ) addObject:(NSString *)uuid ;

/**
 删除 UUID
 
 */
+ (void ) removeObject;
@end

.m

//
//  KeyChainManager.m
//  ChartDemo
//
//  Created by user on 2017/9/27.
//  Copyright © 2017年 MK. All rights reserved.
//

#import "KeyChainManager.h"
#import 

@implementation KeyChainManager


static NSString * const MY_UUIDDictionaryKEY = @"com.MK.ChartDemo";
static NSString * const MY_UUIDKEY = @"com.MK.ChartDemoKey";

+ (NSString *)isExistUUID{
    
    NSString * uuid = (NSString *)[self showUUID];
    NSLog(@"UUid : %@", uuid);
    return uuid;
    
}

+ (void) addObject:(NSString *)uuid{
    
    if (uuid) {
        
        NSMutableDictionary * dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:uuid,MY_UUIDDictionaryKEY, nil];
        NSMutableDictionary * query = [self getKeyChainQuery:MY_UUIDKEY];
        
        if (query) {
            
            SecItemDelete((CFDictionaryRef)query);
            
            [query setObject:[NSKeyedArchiver archivedDataWithRootObject:dict] forKey:(id)kSecValueData];
            
            SecItemAdd((CFDictionaryRef)query, NULL);
        }
    }
    
    
    
}

+ (void)removeObject{
    
    SecItemDelete((CFDictionaryRef)[self getKeyChainQuery:MY_UUIDKEY]);
    
}

+ (id)showUUID{
    
    id selectObject = nil;
    NSMutableDictionary * query = [self getKeyChainQuery:MY_UUIDKEY];
    
    [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
    [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
    
    CFDataRef data = NULL;
    if (SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&data) == noErr) {
        
        @try{
            
            selectObject = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)data];
            
        }@catch (NSException * e){
            
            NSLog(@"解包异常 %@ : %@", query, e);
            
        }@finally{
            
        }
    }
        
        if (data) {
            CFRelease(data);
            
        }
    
    if (selectObject) {
        
        return [((NSDictionary *)selectObject) objectForKey:MY_UUIDDictionaryKEY];
    }
        
        return nil;

}

/**
 获取KeyChain的查询

 @param key 关键字
 @return 获得查询的 ref
 */
+ (NSMutableDictionary *) getKeyChainQuery:(NSString *) key{
    
    return [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassGenericPassword,(id)kSecClass,key, (id)kSecAttrService,key, (id)kSecAttrAccount,(id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,nil];
}


@end
  

AppDelegate中的调用:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
        if (![KeyChainManager isExistUUID]) {
        
        [KeyChainManager addObject:[[NSUUID UUID] UUIDString]];
    }

    return YES;
}
   
    

你可能感兴趣的:(OC(廿二):识别 iOS 设备的唯一性策略--UUID+keyChain存储)