Keychainを使用してiOSのUDID問題を解決
3723 ワード
iOS 5以前は
“Do not use the
Appleは
さらにAppleは、次の2つの方法を提供しています.IFA/IDFA(Identifier for Advertisers)は、アプリケーションが広告を表示し、ユーザーがリセットできることに限られる. IFF/IFFV(Identifier for Vendor):アプリケーションが削除されると、UUIDもリセットされます. ソリューション:
Keychainを用いる、UUIDをパスワード情報として記憶する.
大まかな流れ:
1,
2,
3、以上のいずれもサポートされていない場合は、
最後に、Keychainに追加
Provisioning profileを更新すると、Keychain dataが失われるので、UUIDを
99%参考Persistent,Cross-Install Device Identifier on iOS:Using Keychain:https://blog.onliquid.com/persistent-device-unique-identifier-ios-keychain
ソース:https://gist.github.com/miguelcma/e8f291e54b025815ca46
uniqueIdentifier
でデバイスのUDIDを取得することができたが、プライバシーの問題でAppleはこの方法でUDIDを取得することを禁止した.“Do not use the
uniqueIdentifier
property. To create a unique identifier specific to your app, you can call the CFUUIDCreate function to create a UUID, and write it to the defaults database using the NSUserDefaults class.” Appleは
CFUUIDCreate
メソッドを使用してUUIDを作成し、NSUserDefaults
に保存することを提案する.さらにAppleは、次の2つの方法を提供しています.
Keychainを用いる、UUIDをパスワード情報として記憶する.
大まかな流れ:
1,
AdSupport
によりUUIDを取得する(理由AdSupport
はアプリケーションを跨ぐことができる)+ (NSString *)appleIFA {
NSString *ifa = nil;
Class ASIdentifierManagerClass = NSClassFromString(@"ASIdentifierManager");
if (ASIdentifierManagerClass) { // a dynamic way of checking if AdSupport.framework is available
SEL sharedManagerSelector = NSSelectorFromString(@"sharedManager");
id sharedManager = ((id (*)(id, SEL))[ASIdentifierManagerClass methodForSelector:sharedManagerSelector])(ASIdentifierManagerClass, sharedManagerSelector);
SEL advertisingIdentifierSelector = NSSelectorFromString(@"advertisingIdentifier");
NSUUID *advertisingIdentifier = ((NSUUID* (*)(id, SEL))[sharedManager methodForSelector:advertisingIdentifierSelector])(sharedManager, advertisingIdentifierSelector);
ifa = [advertisingIdentifier UUIDString];
}
return ifa;
}
2,
AdSupport
がサポートされていない場合はIFB/Identifier for Vendorを使用する+ (NSString *)appleIFV {
if(NSClassFromString(@"UIDevice") && [UIDevice instancesRespondToSelector:@selector(identifierForVendor)]) {
// only available in iOS >= 6.0
return [[UIDevice currentDevice].identifierForVendor UUIDString];
}
return nil;
}
3、以上のいずれもサポートされていない場合は、
CFUUIDRef
を使用して手動でUUIDを作成します.+ (NSString *)randomUUID {
if(NSClassFromString(@"NSUUID")) { // only available in iOS >= 6.0
return [[NSUUID UUID] UUIDString];
}
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef cfuuid = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);
CFRelease(uuidRef);
NSString *uuid = [((__bridge NSString *) cfuuid) copy];
CFRelease(cfuuid);
return uuid;
}
最後に、Keychainに追加
+ (void)setValue:(NSString *)value forKey:(NSString *)key inService:(NSString *)service {
NSMutableDictionary *keychainItem = [[NSMutableDictionary alloc] init];
keychainItem[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;
keychainItem[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAlways;
keychainItem[(__bridge id)kSecAttrAccount] = key;
keychainItem[(__bridge id)kSecAttrService] = service;
keychainItem[(__bridge id)kSecValueData] = [value dataUsingEncoding:NSUTF8StringEncoding];
SecItemAdd((__bridge CFDictionaryRef)keychainItem, NULL);
}
Provisioning profileを更新すると、Keychain dataが失われるので、UUIDを
NSUserDefault
でバックアップする必要があります.[[NSUserDefaults standardUserDefaults] setObject:@”123456-1234-1234-12345678” forKey:@"deviceUID"];
[[NSUserDefaults standardUserDefaults] synchronize];
99%参考Persistent,Cross-Install Device Identifier on iOS:Using Keychain:https://blog.onliquid.com/persistent-device-unique-identifier-ios-keychain
ソース:https://gist.github.com/miguelcma/e8f291e54b025815ca46
bug,