天天看點

iOS-通過UUID來擷取iOS裝置唯一辨別

在之前的版本是可以使用UDID擷取iOS裝置唯一辨別,

NSString *udidString = [[UIDevice currentDevice] uniqueIdentifier];
           

但是iOS5及以後,被蘋果禁止使用了(棄用了)

而直接擷取的UUID系統不會存儲,每次調用的時候都會獲得一個新的UUID标示符

一般擷取UUID的方法如下

iOS-通過UUID來擷取iOS裝置唯一辨別

我們可以通過持久存儲這個辨別符,來保證即使重新加載,删除後重裝應用都能夠唯一辨別,以下的方式通過擷取到UUID後存入系統中的keychain中,來保證以後每次可以得到相同的唯一标志。

代碼如下:

#import "UUIDTool.h"

NSString * const kUUIDKey = @"com.myApp.uuid";

@implementation UUIDTool

#pragma mark - 擷取到UUID後存入系統中的keychain中

+ (NSString *)getUUIDInKeychain {

    // 1.直接從keychain中擷取UUID

    NSString *getUDIDInKeychain = (NSString *)[UUIDTool load:kUUIDKey];

    NSLog(@"從keychain中擷取UUID%@", getUDIDInKeychain);

    // 2.如果擷取不到,需要生成UUID并存入系統中的keychain

    if (!getUDIDInKeychain || [getUDIDInKeychain isEqualToString:@""] || [getUDIDInKeychain isKindOfClass:[NSNull class]]) {

        // 2.1 生成UUID

        CFUUIDRef puuid = CFUUIDCreate(nil);

        CFStringRef uuidString = CFUUIDCreateString(nil, puuid);

        NSString *result = (NSString *)CFBridgingRelease(CFStringCreateCopy(NULL, uuidString));

        CFRelease(puuid);

        CFRelease(uuidString);

        NSLog(@"生成UUID:%@",result);

        // 2.2 将生成的UUID儲存到keychain中

        [UUIDTool save:kUUIDKey data:result];

        // 2.3 從keychain中擷取UUID

        getUDIDInKeychain = (NSString *)[UUIDTool load:kUUIDKey];

    }

    return getUDIDInKeychain;

}

#pragma mark - 删除存儲在keychain中的UUID

+ (void)deleteKeyChain {

    [self delete:kUUIDKey];

}

#pragma mark - 私有方法

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

    return [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassGenericPassword,(id)kSecClass,service,(id)kSecAttrService,service,(id)kSecAttrAccount,(id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible, nil];

}

// 從keychain中擷取UUID

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

    id ret = nil;

    NSMutableDictionary *keychainQuery = [self getKeyChainQuery:service];

    [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 *exception) {

            NSLog(@"Unarchive of %@ failed: %@", service, exception);

        }

        @finally {

            NSLog(@"finally");

        }

    }

    if (keyData) {

        CFRelease(keyData);

    }

    NSLog(@"ret = %@", ret);

    return ret;

}

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

    NSMutableDictionary *keychainQuery = [self getKeyChainQuery:service];

    SecItemDelete((CFDictionaryRef)keychainQuery);

}

// 将生成的UUID儲存到keychain中

+ (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);

}

另外附上GitHub上的Demo連結:https://github.com/rambocai/ZYUUID-Emon.git

作者:雪落傾城

連結:https://www.jianshu.com/p/0dce89cdf9f6

來源:簡書

簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。