1. 程式人生 > >如何獲取 iOS 裝置的唯一 ID

如何獲取 iOS 裝置的唯一 ID

CFUUID
每次呼叫 CFUUIDCreate 系統都會返回一個全新的唯一 ID. 如果想永久儲存這個 ID,需要自己處理,可以一次獲取後,存在 NSUserDefaults,Keychain,Pasteboard 等,下次再從這其中取出。

- (NSString *)createUUID
{
    CFUUIDRef uuid = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, uuid);
    CFRelease(uuid);
    return (__bridge NSString *)
string; }

NSUUID

NSString *uuid = [[NSUUID UUID] UUIDString];

和 CFUUID 一樣, 每次呼叫 NSUUID 都會獲取到一個新的 UUID,需要自己儲存獲取到的 UUID。

Advertiser Identifier

NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

advertisingIdentifier 由系統保持唯一性,同一個裝置上所有應用獲取到 advertisingIdentifier 的都是一樣的。但有兩種方法可以修改這個值,重置系統(設定 -> 通用 -> 還原 -> 抹掉所有內容和設定)或者重置廣告識別符號(設定 -> 隱私 -> 廣告 -> 還原廣告識別符號),在這兩種情況下都會生成新的advertisingIdentifier,依然無法保證裝置唯一。

Identifier for Vendor (IDFV)

NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

蘋果的官方文件:

The value in this property remains the same while the app (or another app from the same vendor) is installed on the iOS device. The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them. The value can also change when installing test builds using Xcode or when installing an app on a device using ad-hoc distribution. Therefore, if your app stores the value of this property anywhere, you should gracefully handle situations where the identifier changes.

在同一個裝置上不同的 vendor 下的應用獲取到的 IDFV 是不一樣的,而同一個 vendor 下的不同應用獲取的 IDFV 都是一樣的。但如果使用者刪除了這個 vendor 的所有應用,再重新安裝它們,IDFV 就會被重置,和之前的不一樣,也不是裝置唯一的。

什麼是 Vendor? 一個 Vendor 是 CFBundleIdentifier——應用識別符號的字首,如下

25574-f5181da917a91405.jpg

舉個例子, com.doubleencore.app1 和 com.doubleencore.app2 會獲取到相同的 IDFV,因為它們有相通的 com.doubleencore。但 com.massivelyoverrated 和 net.doubleencore 獲取到的則是不一樣的 IDFV。

以上所有 ID 都不能保證裝置唯一,有什麼方式可以獲取裝置唯一 ID?

以 IDFV 為例,為保證使用者在刪除應用時,取到的 IDFV 仍和之前的一樣,可以藉助 Keychain。使用 SAMKeychain,可以很方便地設定 keychain。 需要注意的是, keychain 在同一個蘋果賬號的不同裝置下是同步的,需要設定query.synchronizationMode = SAMKeychainQuerySynchronizationModeNo;,不在裝置間同步這個值,這樣不同裝置獲取到的便是不同的 ID,程式碼如下:

-(NSString *)getUniqueDeviceIdentifierAsString
{
    NSString *appName=[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];

    NSString *strApplicationUUID =  [SAMKeychain passwordForService:appName account:@"incoding"];
    if (strApplicationUUID == nil)
    {
        strApplicationUUID  = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

        NSError *error = nil;
        SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init];
        query.service = appName;
        query.account = @"incoding";
        query.password = strApplicationUUID;
        query.synchronizationMode = SAMKeychainQuerySynchronizationModeNo;
        [query save:&error];

    }

    return strApplicationUUID;
}

參考資料:
The Developer’s Guide to Unique Identifiers
How to preserve identifierForVendor in ios after uninstalling ios app on device?
What’s the difference between UUID, GUID and UDID?