天天看点

关于设备唯一标示UUID的问题与数据存储在KeyChain里边

直接上代码:

UUID.h  代码如下:

#import <Foundation/Foundation.h>

@interface UUID : NSObject

+(NSString *)getUUID;

@end

UUID.m 代码如下:

#import "UUID.h"

#import "KeyChainStore.h"

#define  KEY_USERNAME_PASSWORD @"com.company.app.usernamepassword"

@implementation UUID

+(NSString *)getUUID

{

    NSString * strUUID = (NSString *)[KeyChainStore load:@"com.company.app.usernamepassword"];

   //首次执行该方法时,uuid为空

    if ([strUUID isEqualToString:@""] || !strUUID)

    {

        //生成一个uuid的方法

        CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);

        strUUID = (NSString *)CFBridgingRelease(CFUUIDCreateString (kCFAllocatorDefault,uuidRef));

        //将该uuid保存到keychain

        [KeyChainStore save:KEY_USERNAME_PASSWORD data:strUUID];

    }

    return strUUID;

}

@end

KeyChainStore.h 代码如下

#import <Foundation/Foundation.h>

@interface KeyChainStore : NSObject

+ (void)save:(NSString *)service data:(id)data;

+ (id)load:(NSString *)service;

+ (void)deleteKeyData:(NSString *)service;

@end

KeyChainStore.m 代码如下

//

//  KeyChainStore.m

//  DaBangHui

//

//  Created by DBH on 16/4/15.

//  Copyright © 2016年张梦磊. All rights reserved.

//

#import "KeyChainStore.h"

@implementation KeyChainStore

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

    return [NSMutableDictionary dictionaryWithObjectsAndKeys:

            (id)kSecClassGenericPassword,(id)kSecClass,

            service, (id)kSecAttrService,

            service, (id)kSecAttrAccount,

            (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,

            nil];

}

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

    //Get search dictionary

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    //Delete old item before add new item

    SecItemDelete((CFDictionaryRef)keychainQuery);

    //Add new object to search dictionary(Attention:the data format)

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

    //Add item to keychain with the search dictionary

    SecItemAdd((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:(id)kSecReturnData];

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

    CFDataRef keyData = NULL;

    if (SecItemCopyMatching((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;

}

+ (void)deleteKeyData:(NSString *)service {

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    SecItemDelete((CFDictionaryRef)keychainQuery);

}

@end

直接调用  

[UUID getUUID]