iOS開發日記20-7.0之後擷取裝置唯一標識

來源:互聯網
上載者:User

標籤:

今天博主有一個擷取裝置唯一標識的需求,遇到了一些困痛點,在此和大家分享,希望能夠共同進步.

在iOS7.0之前,擷取裝置唯一標識的方法主要是擷取UDID或MAC地址,但是在iOS7.0之後,為了保護使用者隱私,蘋果把他們都禁止了,使得裝置的資料追蹤變得越來越難.

iOS7.0之後,擷取裝置唯一標識的方法主要有兩種:

1.廣告標識符 IDFA

蘋果為了完善自己的生態圈,在2010年前後推出了iAd廣告網路。那麼這個IDFA和這個iAd的關係就不言自喻了。如果不瞭解廣告也沒關係,簡單來講,現在的互連網廣告精準投放需要瞭解使用者資料,基於這些資訊使得廣告更有效率,唯一標識就很重要,就用到了IDFA.

advertisingIdentifier在AdSupport.framework的ASIdentifierManager類中,是其中兩個屬性中的一個.

可以說,用這個IDFA標識裝置應該還是很精準的(不然iAd就徹底不用玩了),很多開發人員還在使用.

2.IDFV+Key Chain

由於IDFV刪除app之後再重新安裝,標識符就變了,要解決這個問題,可以把第一次產生的ID儲存到Key Chain中,刪除app之後Key Chain中的資料還在就OK了.

    #define KEY_UDID            @"KEY_UDID"  

    #define KEY_IN_KEYCHAIN     @"KEY_IN_KEYCHAIN"    

    #import <Security/Security.h>  

    #import "APPIdentificationManage.h"  

    @implementation APPIdentificationManage  

    singleton_implementation(APPIdentificationManage)  

    #pragma mark 擷取UUID  

    /** 

     *此uuid在相同的一個程式裡面-相同的vindor-相同的裝置下是不會改變的 

     *此uuid是唯一的,但應用刪除再重新安裝後會變化,採取的措施是:只擷取一次儲存在鑰匙串中,之後就從鑰匙串中擷取 

     **/  

    - (NSString *)openUDID  

{  

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

    return identifierForVendor;  

}  

    #pragma mark 儲存UUID到鑰匙串  

    - (void)saveUDID:(NSString *)udid  

{  

    NSMutableDictionary *udidKVPairs = [NSMutableDictionary dictionary];  

    [udidKVPairs setObject:udid forKey:KEY_UDID];  

    [[APPIdentificationManage sharedAPPIdentificationManage] save:KEY_IN_KEYCHAIN data:udidKVPairs];  

}  

    #pragma mark 讀取UUID  

    /** 

     *先從記憶體中擷取uuid,如果沒有再從鑰匙串中擷取,如果還沒有就產生一個新的uuid,並儲存到鑰匙串中供以後使用 

     **/  

    - (id)readUDID  

{  

    if (_uuid == nil || _uuid.length == 0) {  

    NSMutableDictionary *udidKVPairs = (NSMutableDictionary *)[[APPIdentificationManage sharedAPPIdentificationManage] load:KEY_IN_KEYCHAIN];    

    NSString *uuid = [udidKVPairs objectForKey:KEY_UDID];  

    if (uuid == nil || uuid.length == 0) {  

    uuid = [self openUDID];  

     [self saveUDID:uuid];  

     }  

      _uuid = uuid;  

   }  

    return _uuid;  

}  

    #pragma mark 刪除UUID  

    - (void)deleteUUID  

{  

     [APPIdentificationManage delete:KEY_IN_KEYCHAIN];  

}  

    #pragma mark 查詢鑰匙串  

    - (NSMutableDictionary *)getKeychainQuery:(NSString *)service {  

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

}  

    #pragma mark 將資料儲存到鑰匙串  

    - (void)save:(NSString *)service data:(id)data {  

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  

    SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);  

    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge_transfer id)kSecValueData];  

    SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);  

}  

    #pragma mark 載入鑰匙串中資料  

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

    id ret = nil;  

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  

    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];  

    [keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];  

    CFDataRef keyData = NULL;  

    if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {  

    @try {  

            ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];  

        } @catch (NSException *e) {  

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

       } @finally {  

       }  

   }  

    return ret;  

}  

    #pragma mark 刪除鑰匙串中資料  

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

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  

    SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);  

}  

@end  

iOS開發日記20-7.0之後擷取裝置唯一標識

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.