iOS UDID與UUID

1.UDID

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

是一串由40位16進制數組成的字符串,用以標識惟一的設備,如今想經過代碼獲取是不可能的了,若是你想看看你設備的UDID,能夠經過iTunes來查看。github

  • 蘋果從iOS5開始就移除了經過代碼訪問UDID的權限,因此碼農想知道用戶設備的UDID,是不行的。
  • 對於已越獄了的設備,UDID並非惟一的。使用Cydia插件UDIDFaker,能夠爲每個應用分配不一樣的UDID。 因此UDID做爲標識惟一設備的用途已經不大了。

關於獲取UDID的代碼(iOS5以後已經廢掉並被AppStore封殺)數組

[[UIDevice currentDevice] uniqueIdentifier];安全

2.UUID

設備惟一標識 UUID(Universally Unique IDentifier)bash

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

  • 同一設備上的不一樣應用的UUID是互斥的,即能在改設備上標識應用。因此一些人推測,這個UUID應該是根據設備標識和應用標識生成惟一標識,再通過加密而來的(純推測)。
  • 官方推薦的方法是,每一個應用內建立一個UUID來做爲惟一標誌,並將之存儲,可是這個解決方法明顯不能接受!
  • 你每次建立的UUID都是不同的,意味着,你卸載後從新安裝這個軟件,生成的UUID就不同了,沒法達到咱們將之做爲數據分析的惟一標識符的要求。

關於獲取UUID的代碼:框架

[[UIDevice currentDevice] identifierForVendor]; 不過,設備惟一標示的問題仍然沒有解決:若是你刪除應用而後再次安裝,這個identifierForVendor的值就變了。ide

2.獲取設備惟一標識符的推薦新方案

思路

  • 經過調用CFFUUIDCreate函數來生成機器惟一標識符UUID。但每次調用該函數返回的字符串都不同,因此第一次調用後需把該字符串存儲起來。
  • 儘管CFFUUIDCreate每次獲取的UUID會發生變化,最理想的是能夠保存在鑰匙串keychain裏面,並以此做爲標識用戶設備的惟一標識符。

2.1關於獲取UUID的官方方案

- (NSString *) uniqueString
{
   CFUUIDRef unique = CFUUIDCreate(kCFAllocatorDefault);
   NSString *result = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, unique) autorelease];
   CFRelease(unique);
   return result;
}
複製代碼

2.2基於SSKeychain的惟一識別碼方案

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

參考代碼:ui

- (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;
}
複製代碼

2.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;
}
複製代碼

SAMKeyChains更多詳細用法說明能夠看SAMKeyChains Documentation

轉載自:iOS設備惟一標識符關於UDID代替方案:基於UUID和SSKeychain生成惟一標識符新方法

相關文章
相關標籤/搜索