// // Copyright (c) 2015年 Anson. All rights reserved. // #import "LCUDIDTool.h" #define LAUDIDKEY_EXTENTION_FLAG @"LAUDID-KEY" @interface LCUDIDTool() { NSString *_udid; } @end @implementation LCUDIDTool static LCUDIDTool *oneInstance; + (instancetype)shareInstance { @synchronized(self) { if (oneInstance == nil) { oneInstance = [[self alloc]init]; } } return oneInstance; } //储存keyChain - (void)saveKey:(NSString *)service value:(NSString *)value { //Get search dictionary NSMutableDictionary *keychainQuery = [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]; CFDictionaryRef keychainQueryRef = (__bridge_retained CFDictionaryRef)keychainQuery; //Delete old item before add new item SecItemDelete(keychainQueryRef); //Add new object to search dictionary(Attention:the data format) [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:value] forKey:(__bridge_transfer id)kSecValueData]; //Add item to keychain with the search dictionary SecItemAdd(keychainQueryRef, NULL); CFRelease(keychainQueryRef); } //获取keyChain - (NSString *)getWithKey:(NSString *)service { NSString *ret = nil; NSMutableDictionary *keychainQuery = [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]; //Configure the search setting [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 - #pragma mark UUIDString - (NSString *)UDIDString { if(_udid!=nil) { return _udid; } //根据bundleID 生产一个UDID_KEY //从keychain中取出对应UDID_KEY的值 如果没有那么生产一个随机的UUID 写入keychain 并返回 NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier]; NSString *UDID_KEY = [NSString stringWithFormat:@"%@-%@",LAUDIDKEY_EXTENTION_FLAG, bundleID]; NSString *uuidString ; @try { uuidString = [self getWithKey:UDID_KEY]; } @catch (NSException *exception) { return nil; } @finally { } if(uuidString && [uuidString length]) { _udid = uuidString; NSLog(@"-%@", uuidString); return uuidString; } @try { CFUUIDRef uuidRef = CFUUIDCreate(nil); CFStringRef stringRef = CFUUIDCreateString(nil, uuidRef); uuidString = (NSString *)CFBridgingRelease(CFStringCreateCopy(nil, stringRef)); CFRelease(uuidRef); CFRelease(stringRef); [self saveKey:UDID_KEY value:uuidString]; _udid = uuidString; return uuidString ; } @catch (NSException *exception) { return nil; } } @end