@interface NSUUIDManager : NSObject
+ (NSString*)UUID;
@end
#import
#include
#include
#include
#include
@implementation NSUUIDManager
static const char kKeychainUUIDItemIdentifier[] = "UUID";
+ (NSString*)UUID
{
NSString *uuid = [NSUUIDManager getUUIDFromKeyChain];
if (!uuid) {
NSString *sysVersion = [UIDevice currentDevice].systemVersion;
CGFloat version = [sysVersion floatValue];
if (version >= 7.0) {
uuid = [NSUUIDManager get_IdentifierForVendor];
}else{
uuid = @"NULL";
}
[NSUUIDManager setUUIDToKeyChain:uuid];
}
return uuid;
}
+ (NSString*)get_IdentifierForVendor
{
return [[UIDevice currentDevice].identifierForVendor UUIDString];
}
#pragma mark -
#pragma mark Helper Method for make identityForVendor consistency
+ (NSString*)getUUIDFromKeyChain
{
NSMutableDictionary *dictForQuery = [[NSMutableDictionary alloc] init];
[dictForQuery setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
// set Attr Description for query
[dictForQuery setValue:[NSString stringWithUTF8String:kKeychainUUIDItemIdentifier]
forKey:(NSString *)kSecAttrDescription];
// set Attr Identity for query
NSData *keychainItemID = [NSData dataWithBytes:kKeychainUUIDItemIdentifier
length:strlen(kKeychainUUIDItemIdentifier)];
[dictForQuery setObject:keychainItemID forKey:(id)kSecAttrGeneric];
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecMatchCaseInsensitive];
[dictForQuery setValue:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
OSStatus queryErr = noErr;
NSData *uuidValue = nil;
NSString *uuid = nil;
queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, (CFTypeRef*)&uuidValue);
NSMutableDictionary *dict = nil;
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, (CFTypeRef*)&dict);
if (queryErr == errSecItemNotFound) {
NSLog(@"KeyChain Item: %@ not found!!!", [NSString stringWithUTF8String:kKeychainUUIDItemIdentifier]);
}
else if (queryErr != errSecSuccess) {
NSLog(@"KeyChain Item query Error!!! Error code:%d", queryErr);
}
if (queryErr == errSecSuccess) {
NSLog(@"KeyChain Item: %@", uuidValue);
if (uuidValue) {
uuid = [NSString stringWithUTF8String:uuidValue.bytes];
}
}
return uuid;
}
+ (BOOL)setUUIDToKeyChain:(NSString*)uuid
{
NSMutableDictionary *dictForAdd = [[NSMutableDictionary alloc] init];
[dictForAdd setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[dictForAdd setValue:[NSString stringWithUTF8String:kKeychainUUIDItemIdentifier] forKey:(NSString *)kSecAttrDescription];
[dictForAdd setValue:@"UUID" forKey:(id)kSecAttrGeneric];
// Default attributes for keychain item.
[dictForAdd setObject:@"" forKey:(id)kSecAttrAccount];
[dictForAdd setObject:@"" forKey:(id)kSecAttrLabel];
const char *uuidStr = [uuid UTF8String];
NSData *keyChainItemValue = [NSData dataWithBytes:uuidStr length:strlen(uuidStr)];
[dictForAdd setValue:keyChainItemValue forKey:(id)kSecValueData];
OSStatus writeErr = noErr;
if ([NSUUIDManager getUUIDFromKeyChain]) { // there is item in keychain
[NSUUIDManager updateUUIDInKeyChain:uuid];
return YES;
}
else { // add item to keychain
writeErr = SecItemAdd((CFDictionaryRef)dictForAdd, NULL);
if (writeErr != errSecSuccess) {
NSLog(@"Add KeyChain Item Error!!! Error Code:%d", writeErr);
return NO;
}
else {
NSLog(@"Add KeyChain Item Success!!!");
return YES;
}
}
return NO;
}
+ (BOOL)removeUUIDFromKeyChain
{
NSMutableDictionary *dictToDelete = [[NSMutableDictionary alloc] init];
[dictToDelete setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
NSData *keyChainItemID = [NSData dataWithBytes:kKeychainUUIDItemIdentifier length:strlen(kKeychainUUIDItemIdentifier)];
[dictToDelete setValue:keyChainItemID forKey:(id)kSecAttrGeneric];
OSStatus deleteErr = noErr;
deleteErr = SecItemDelete((CFDictionaryRef)dictToDelete);
if (deleteErr != errSecSuccess) {
NSLog(@"delete UUID from KeyChain Error!!! Error code:%d", deleteErr);
return NO;
}
else {
NSLog(@"delete success!!!");
}
return YES;
}
+ (BOOL)updateUUIDInKeyChain:(NSString*)uuid
{
NSMutableDictionary *dictForQuery = [[NSMutableDictionary alloc] init];
[dictForQuery setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
NSData *keychainItemID = [NSData dataWithBytes:kKeychainUUIDItemIdentifier
length:strlen(kKeychainUUIDItemIdentifier)];
[dictForQuery setValue:keychainItemID forKey:(id)kSecAttrGeneric];
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecMatchCaseInsensitive];
[dictForQuery setValue:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
NSDictionary *queryResult = nil;
SecItemCopyMatching((CFDictionaryRef)dictForQuery, (CFTypeRef*)&queryResult);
if (queryResult) {
NSMutableDictionary *dictForUpdate = [[NSMutableDictionary alloc] init];
[dictForUpdate setValue:[NSString stringWithUTF8String:kKeychainUUIDItemIdentifier] forKey:(NSString *)kSecAttrDescription];
[dictForUpdate setValue:keychainItemID forKey:(id)kSecAttrGeneric];
const char *uuidStr = [uuid UTF8String];
NSData *keyChainItemValue = [NSData dataWithBytes:uuidStr length:strlen(uuidStr)];
[dictForUpdate setValue:keyChainItemValue forKey:(id)kSecValueData];
OSStatus updateErr = noErr;
// First we need the attributes from the Keychain.
NSMutableDictionary *updateItem = [NSMutableDictionary dictionaryWithDictionary:queryResult];
// Second we need to add the appropriate search key/values.
// set kSecClass is Very important
[updateItem setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
updateErr = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)dictForUpdate);
if (updateErr != errSecSuccess) {
NSLog(@"Update KeyChain Item Error!!! Error Code:%d", updateErr);
return NO;
}
else {
NSLog(@"Update KeyChain Item Success!!!");
return YES;
}
}
return NO;
}
@end
#pragma mark -┏━━━━━━━━━━━━━━━━设置设备的唯一标示符━━━━━━━━━━━━━━━━━┓
#pragma mark -IdentifierForVendor(厂商标识符)
NSString *uuid = [[[UIDevice currentDevice] identifierForVendor ]UUIDString];
NSLog(@"%@",uuid);
#pragma mark -将IdentifierForVendor(厂商标识符)存储在钥匙串里
NSString *uuid_2 = [NSUUIDManager UUID];
NSLog(@"%@",uuid_2);
#pragma mark -┗━━━━━━━━━━━━━━━━设置设备的唯一标示符━━━━━━━━━━━━━━━━━┛
uuid 删除后在安装,每次值不一致
uuid_2 删除后在安装,每次保持一致
注:
1.NSUUIDManager.m
2.引入Security.framework