iOS-通過(guò)UUID來(lái)獲取iOS設(shè)備唯一標(biāo)識(shí)

在之前的版本是可以使用UDID獲取iOS設(shè)備唯一標(biāo)識(shí),

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

但是iOS5及以后,被蘋(píng)果禁止使用了(棄用了)

而直接獲取的UUID系統(tǒng)不會(huì)存儲(chǔ),每次調(diào)用的時(shí)候都會(huì)獲得一個(gè)新的UUID標(biāo)示符
一般獲取UUID的方法如下

// 普通的獲取UUID的方法
+ (NSString *)getUUID {
    CFUUIDRef puuid = CFUUIDCreate( nil );
    CFStringRef uuidString = CFUUIDCreateString(nil, puuid);
    NSString *result = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString));
    return result;
}

我們可以通過(guò)持久存儲(chǔ)這個(gè)標(biāo)識(shí)符,來(lái)保證即使重新加載,刪除后重裝應(yīng)用都能夠唯一標(biāo)識(shí),以下的方式通過(guò)獲取到UUID后存入系統(tǒng)中的keychain中,來(lái)保證以后每次可以得到相同的唯一標(biāo)志。
代碼如下:


#import "UUIDTool.h"

// kUUIDKey盡量改成便于區(qū)分App的(有簡(jiǎn)友說(shuō)如果一個(gè)手機(jī)上兩個(gè)App都這樣用相同的kUUIDKey可能會(huì)存在bug,我測(cè)試幾次沒(méi)發(fā)現(xiàn),但是還是建議盡量要區(qū)分開(kāi))
NSString * const kUUIDKey = @"com.myApp.uuid";

@implementation UUIDTool

#pragma mark - 獲取到UUID后存入系統(tǒng)中的keychain中

+ (NSString *)getUUIDInKeychain {
    // 1.直接從keychain中獲取UUID
    NSString *getUDIDInKeychain = (NSString *)[UUIDTool load:kUUIDKey];
    NSLog(@"從keychain中獲取UUID%@", getUDIDInKeychain);
    
    // 2.如果獲取不到,需要生成UUID并存入系統(tǒng)中的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 - 刪除存儲(chǔ)在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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容