iOS UDID與UUID

iOS UDID與UUID

1.UDID

通用唯一識別碼 UDID(Unique Device Identifier)

是一串由40位16進制數組成的字符串,用以標識唯一的設備,現在想通過代碼獲取是不可能的了,如果你想看看你設備的UDID,可以通過iTunes來查看。

蘋果從iOS5開始就移除了通過代碼訪問UDID的權限,所以碼農想知道用戶設備的UDID,是不行的。
對於已越獄了的設備,UDID並不是唯一的。使用Cydia插件UDIDFaker,可以爲每一個應用分配不同的UDID。 所以UDID作爲標識唯一設備的用途已經不大了。
關於獲取UDID的代碼(iOS5之後已經廢掉並被AppStore封殺)

[[UIDevice currentDevice] uniqueIdentifier];

2.UUID

設備唯一標識 UUID(Universally Unique IDentifier)

是基於iOS設備上面某個單個的應用程序,只要用戶沒有完全刪除應用程序,則這個UUID在用戶使用該應用程序的時候一直保持不變。如果用戶刪除了這個應用程序,然後再重新安裝,那麼這個UUID已經發生了改變。

同一設備上的不同應用的UUID是互斥的,即能在改設備上標識應用。所以一些人推測,這個UUID應該是根據設備標識和應用標識生成唯一標識,再經過加密而來的(純推測)。
官方推薦的方法是,每個應用內創建一個UUID來作爲唯一標誌,並將之存儲,但是這個解決方法明顯不能接受!
你每次創建的UUID都是不一樣的,意味着,你卸載後重新安裝這個軟件,生成的UUID就不一樣了,無法達到我們將之作爲數據分析的唯一標識符的要求。
關於獲取UUID的代碼:

[[UIDevice currentDevice] identifierForVendor]

不過,設備唯一標示的問題仍然沒有解決:如果你刪除應用然後再次安裝,這個identifierForVendor的值就變了。

3.獲取設備唯一標識符的推薦新方案

思路
通過調用CFFUUIDCreate函數來生成機器唯一標識符UUID。但每次調用該函數返回的字符串都不一樣,所以第一次調用後需把該字符串存儲起來。
儘管CFFUUIDCreate每次獲取的UUID會發生變化,最理想的是可以保存在鑰匙串keychain裏面,並以此作爲標識用戶設備的唯一標識符。

3.1關於獲取UUID的官方方案
- (NSString *) uniqueString
{
   CFUUIDRef unique = CFUUIDCreate(kCFAllocatorDefault);
   NSString *result = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, unique) autorelease];
   CFRelease(unique);
   return result;
}

複製代碼

3.2基於SSKeychain的唯一識別碼方案

如上獲取的UUID,基於Git上的一個第三方庫SSKeychain,可以將UUID保存在keychain裏面,每次調用先檢查鑰匙串裏面有沒有,有則使用,沒有則寫進去,保證其唯一性.

參考代碼:

- (NSString *)getNewUniqueIdNum{
    
    NSString *uuidStr = [SSKeychain passwordForService:@"com.test.app1" account:@"user"];
    if (!uuidStr || [uuidStr isEqualToString:@""])
    {
        CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
        uuidStr = (__bridge NSString *)CFUUIDCreateString(kCFAllocatorDefault ,uuidRef);
        [SSKeychain setPassword:[NSString stringWithFormat:@"%@", uuidStr] forService:@"com.test.app1"account:@"user"];
    }
    return uuidStr;
}

不同於上面調用的字符串轉換(__bridge NSString *),另一種寫法:

- (NSString *)getNewUniqueIdNum{
    
    NSString *identifierNumber = [SSKeychain passwordForService:@"com.test.app1"account:@"user"];
    CFUUIDRef uuidRef = CFUUIDCreate(NULL);
    assert(uuidRef != NULL);
    CFStringRef uuidStrRef = CFUUIDCreateString(NULL, uuidRef);
    
    if (!identifierNumber){
        
        [SSKeychain setPassword: [NSString stringWithFormat:@"%@", uuidStrRef] forService:@"com.test.app1"account:@"user"];
        identifierNumber = [SSKeychain passwordForService:@"com.test.app1"account:@"user"];
    }
    return identifierNumber;
}
3.3其它方案

不同於如上SSKeychain,基於一個第三方庫SAMKeyChains。SAMKeyChains對蘋果安全框架API進行了簡單封裝,支持對存儲在鑰匙串中密碼、賬戶進行訪問,包括讀取、刪除和設置。SAMKeyChains使用簡單,通過實例代碼便可掌握。

基於SAMKeyChains方案的參考代碼:

+ (NSString *)getDeviceId
{
    NSString * currentDeviceUUIDStr = [SAMKeychain passwordForService:@" "account:@"uuid"];
    if (currentDeviceUUIDStr == nil || [currentDeviceUUIDStr isEqualToString:@""])
    {
        NSUUID * currentDeviceUUID  =[[UIDevice currentDevice] identifierForVendor];
        currentDeviceUUIDStr = [currentDeviceUUID UUIDString];
        currentDeviceUUIDStr = [currentDeviceUUIDStr stringByReplacingOccurrencesOfString:@"-" withString:@""];
        currentDeviceUUIDStr = [currentDeviceUUIDStr lowercaseString];
        [SAMKeychain setPassword: currentDeviceUUIDStr forService:@" "account:@"uuid"];
    }
    return currentDeviceUUIDStr;
}

本文轉載自: https://cloud.tencent.com/developer/article/1332168

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章