美文网首页
iOS 唯一标识

iOS 唯一标识

作者: MccReeee | 来源:发表于2017-11-30 14:54 被阅读20次

简单靠谱
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));
    }
}


相关文章

网友评论

      本文标题:iOS 唯一标识

      本文链接:https://www.haomeiwen.com/subject/xepvbxtx.html