IOS7.0唯一“设备ID”的获取方法
ios7.0 以后通过sysctl获得的mac地址已经失效,所有设备均为020000000000.
可以通过苹果的keychain机制,实现设备的唯一ID标示。
具体过程:在app第一次安装时,生成一个唯一的ID,将该ID保存到keychain中。keychain内的id并不会因为app的卸载而失效,下次安装或者更新仍然可以取到这个唯一的ID,从而可以找到这个设备对应的账号。
注:唯一ID的生成,可以通过程序自己的算法如guid,或者用苹果自带的IDFV([[UIDevice currentDevice]] identifierForVendor]]).
以下是具体代码:
static KeychainItemWrapper * s_pWrapper = Nil; // 获取开发者的ID NSString * getAppID() { NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: (id)kSecClassGenericPassword, kSecClass, @"bundleSeedID", kSecAttrAccount, @"", kSecAttrService, (id)kCFBooleanTrue, kSecReturnAttributes, nil]; CFDictionaryRef result = nil; OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&result); if (status == errSecItemNotFound) status = SecItemAdd((CFDictionaryRef)query, (CFTypeRef *)&result); if (status != errSecSuccess) return nil; NSString *accessGroup = [(NSDictionary *)result objectForKey:(id)kSecAttrAccessGroup]; NSArray *components = [accessGroup componentsSeparatedByString:@"."]; NSString *bundleSeedID = [[components objectEnumerator] nextObject]; CFRelease(result); return bundleSeedID; } // 获取设备唯一ID std::string getUniqueID() { if (s_pWrapper == Nil) { #if TARGET_IPHONE_SIMULATOR s_pWrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAPP" accessGroup:Nil]; #else NSString* boundSeedID = getAppID(); NSString* appID = @".com.YourCompany.YourAPP"; NSString* groupID = [boundSeedID stringByAppendingString:appID]; s_pWrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAPP" accessGroup:groupID]; #endif // [s_pWrapper resetKeychainItem]; } // 是否已注册过 NSString *key = [s_pWrapper objectForKey:(id)kSecValueData]; if (key != Nil && key.length > 0) { return [key UTF8String]; } // 7.0系统取IDFV作为唯一标示 NSUUID* uuid = [[UIDevice currentDevice] identifierForVendor]; key = [uuid UUIDString]; // 注册到keychain中 [s_pWrapper setObject:(id)key forKey:(id)kSecAttrAccount]; [s_pWrapper setObject:(id)key forKey:(id)kSecAttrService]; [s_pWrapper setObject:(id)key forKey:(id)kSecValueData]; return [key UTF8String]; }
注:
1、KeychainItemWrapper为apple官方提供的一个sample里面的代码,链接https://developer.apple.com/library/ios/samplecode/GenericKeychain/Listings/Classes_KeychainItemWrapper_m.html
2、在项目的Capabilities属性下,将Keychain sharing改成Enable。项目中会自动添加一个entitlements文件。