简单靠谱
Tool.h
/**
UUID(通用唯一识别码),同一设备不同应用的UUID不同,重装应用也会重新生成,调用CFUUID.h下的API生成。
*/
+ (NSString *)getUUID;
Tool.m
#import <Security/Security.h>
//在Keychain中的标识,这里取bundleIdentifier + UUID
#define KEYCHAIN_IDENTIFIER(a) ([NSString stringWithFormat:@"%@_%@",[[NSBundle mainBundle] bundleIdentifier],a])
#define KCIDisNull(a) (a==nil ||\
a==NULL ||\
(NSNull *)(a)==[NSNull null] ||\
((NSString *)a).length==0)
+ (NSString *)getUUID {
//读取keychain缓存
NSString *deviceID = [self load:KEYCHAIN_IDENTIFIER(@"UUID")];
//不存在,生成UUID
if (KCIDisNull(deviceID))
{
CFUUIDRef uuid_ref = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef uuid_string_ref= CFUUIDCreateString(kCFAllocatorDefault, uuid_ref);
CFRelease(uuid_ref);
deviceID = [NSString stringWithString:(__bridge NSString*)uuid_string_ref];
deviceID = [deviceID lowercaseString];
if (!KCIDisNull(deviceID))
{
[self save:KEYCHAIN_IDENTIFIER(@"UUID") data:deviceID];
}
CFRelease(uuid_string_ref);
}
if (KCIDisNull(deviceID)) {
NSLog(@"get deviceID error!");
}
return deviceID;
}
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
//第一次解锁后可访问,备份
NSDictionary *dic = @{
(__bridge_transfer id)kSecClass:(__bridge_transfer id)kSecClassGenericPassword,
(__bridge_transfer id)kSecAttrService:service,
(__bridge_transfer id)kSecAttrAccount:service,
(__bridge_transfer id)kSecAttrAccessible:(__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock
};
NSMutableDictionary *resultDic = [NSMutableDictionary dictionaryWithCapacity:3];
[resultDic addEntriesFromDictionary:dic];
return resultDic;
}
+ (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<NSCopying>)(kSecValueData)];
SecItemAdd((__bridge_retained CFDictionaryRef)(keychainQuery), NULL);
if (keychainQuery) {
CFRelease((__bridge CFTypeRef)(keychainQuery));
}
}
+ (id)load:(NSString *)service {
id ret = @"";
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id<NSCopying>)(kSecReturnData)];
[keychainQuery setObject:(__bridge_transfer id)(kSecMatchLimitOne) forKey:(__bridge_transfer id<NSCopying>)(kSecMatchLimit)];
CFTypeRef result = NULL;
if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, &result) == noErr)
{
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData*)result];
}
if (keychainQuery) {
CFRelease((__bridge CFTypeRef)(keychainQuery));
}
return ret;
}
+ (void)delete:(NSString *)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((__bridge_retained CFDictionaryRef)(keychainQuery));
if (keychainQuery) {
CFRelease((__bridge CFTypeRef)(keychainQuery));
}
}
网友评论