標籤:sda turn 最好 ons ref 行修改 form figure self
轉自:《iOS擷取裝置的唯一標識的方法總結以及最好的方法》
參考:《擷取iOS裝置唯一標識》
總結一下:
1.代碼採用CFUUID+KeyChain的實現方式。
2.CFUUID、IDFA、IDFV都是可變的(其它方法,比如蘋果內建的UUID和MAC地址基本上被禁止使用),但是IDFA和IDFV不一定都能擷取到(iOS系統不同版本不一定支援),所以直接選擇了CFUUID(iOS2.0就開始支援了)。
PS:
3.代碼中使用stringByReplacingOccurrencesOfString將間隔符-去掉了(原來是這種:CAE1CC3A-92C1-45A5-9F55-932264020358,去掉後變為CAE1CC3A92C145A59F55932264020358)。
4.SdkMgr為自訂類名,根據需要自行修改。
NSString * const KEY_UDID_INSTEAD = @"com.app.uuid.test";+(NSString *)getDeviceUUID{ NSString *getUDIDInKeychain = (NSString *)[SdkMgr load:KEY_UDID_INSTEAD]; if (!getUDIDInKeychain ||[getUDIDInKeychain isEqualToString:@""]||[getUDIDInKeychain isKindOfClass:[NSNull class]]) { CFUUIDRef puuid = CFUUIDCreate( nil ); CFStringRef uuidString = CFUUIDCreateString( nil, puuid ); NSString * result = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString)); CFRelease(puuid); CFRelease(uuidString); //去掉橫線,保留32位長度 NSString *rst = [result stringByReplacingOccurrencesOfString:@"-" withString:@""]; [SdkMgr save:KEY_UDID_INSTEAD data:rst]; getUDIDInKeychain = (NSString *)[SdkMgr load:KEY_UDID_INSTEAD]; } return getUDIDInKeychain;}#pragma mark - private+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service { return [NSMutableDictionary dictionaryWithObjectsAndKeys: (id)kSecClassGenericPassword,(id)kSecClass, service, (id)kSecAttrService, service, (id)kSecAttrAccount, (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible, nil];}+ (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);}+ (id)load:(NSString *)service { id ret = nil; NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Configure the search setting //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue [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:(NSData *)keyData]; } @catch (NSException *e) { NSLog(@"Unarchive of %@ failed: %@", service, e); } @finally { } } if (keyData) CFRelease(keyData); return ret;}+ (void)delete:(NSString *)service { NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; SecItemDelete((CFDictionaryRef)keychainQuery);}@end
iOS擷取UUID