Как сохранить identifierForVendor в ios после удаления ios-приложения на устройстве?
Я разрабатываю приложение iOS, которое вызывает веб-сервис для входа в систему, и в это время я отправляю учетные данные для входа на веб-сервер вместе с идентификатором поставщика(identifierForVendor), чтобы идентифицировать устройство уникально для тех credentials.So пользователь может иметь только одно устройство и одни учетные данные.
я получил identifierForVendor с
NSString *uuid = [[UIDevice currentDevice] identifierForVendor].UUIDString
этот идентификатор будет храниться в базе данных веб-сервера, а также в базе данных устройства.В следующий раз, когда пользователь открывает приложение и попытается загрузка данных с веб-сервера во-первых local identifierForVendor на пользовательском устройстве будет сравниваться с идентификатором, хранящимся на веб-сервере.
проблема возникает, когда пользователь удаляет приложение и переустановить его, я обнаружил, что identifierForVendor изменяется. Так что пользователь не может продолжать дальше.
Я читал документацию apple Документация UIDevice
Как упоминалось там, если все приложение от одного и того же поставщика удаляется с устройства, то во время новой установки любого приложения из того, что поставщик будет приобретать новые identifierForVendor.
Так как же с этим бороться в моем случае ?
8 ответов:
вы можете держать его в связке ключей
-(NSString *)getUniqueDeviceIdentifierAsString { NSString *appName=[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; NSString *strApplicationUUID = [SSKeychain passwordForService:appName account:@"incoding"]; if (strApplicationUUID == nil) { strApplicationUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; [SSKeychain setPassword:strApplicationUUID forService:appName account:@"incoding"]; } return strApplicationUUID; }
как правило, не использовать
identifierForVendor. Вместо этого используйтеNSUUIDчтобы создать пользовательский UUID и сохранить его в связке ключей (потому что связка ключей не удаляется, если приложение удалено и переустановлено).
дополнение к @nerowolfe это ответ.
SSKeychain использует
kSecAttrSynchronizableAnyв режиме синхронизации по умолчанию. Вы, наверное, не хочу!--2--> для синхронизации на нескольких устройствах, так что вот код:// save identifierForVendor in keychain without sync NSError *error = nil; SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; query.service = @"your_service"; query.account = @"your_account"; query.password = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; query.synchronizationMode = SSKeychainQuerySynchronizationModeNo; [query save:&error];
вы можете попробовать использовать брелок чтобы сохранить VendorIdentifier, это будет существовать до тех пор, пока ваше устройство не будет сброшено, даже если вы удалите свое приложение.
ОК. Я не хотел использовать третью сторону-а именно SSKeychain. Так это код, который я пробовал, довольно простой и хорошо работает:
NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]; KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:bundleId accessGroup:nil]; if(![keychainItem objectForKey:(__bridge id)(kSecValueData)]){ NSString *idfa = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; [keychainItem setObject:idfa forKey:(__bridge id)(kSecValueData)]; NSLog(@"saving item %@", [keychainItem objectForKey:(__bridge id)(kSecValueData)]); }else{ NSLog(@"saved item is %@", [keychainItem objectForKey:(__bridge id)(kSecValueData)]); }
Swift версия
func UUID() -> String { let bundleName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String let accountName = "incoding" var applicationUUID = SAMKeychain.passwordForService(bundleName, account: accountName) if applicationUUID == nil { applicationUUID = UIDevice.currentDevice().identifierForVendor!.UUIDString // Save applicationUUID in keychain without synchronization let query = SAMKeychainQuery() query.service = bundleName query.account = accountName query.password = applicationUUID query.synchronizationMode = SAMKeychainQuerySynchronizationMode.No do { try query.save() } catch let error as NSError { print("SAMKeychainQuery Exception: \(error)") } } return applicationUUID }
нет никакого определенного способа связать уникальный номер с устройством больше, это не допускается с руководством по конфиденциальности Apple.
вы можете попытаться сохранить свой собственный уникальный идентификатор в связке ключей, но если пользователь очистит свое устройство, этот идентификатор также исчезнет.
вообще это просто неправильно связать устройство с пользователем, так как вы больше не идентифицируете пользователей, а устройства. Поэтому вы должны просто изменить свой API, чтобы пользователь мог повторно войти в систему и что идентификатор поставщика привязан к учетной записи пользователя.
и что происходит, когда пользователь имеет более одного устройства, как iPhone и iPad, и использует вас приложение на обоих? Поскольку аутентификация основана на уникальном идентификаторе, это невозможно сделать.
я использовал KeychainAccess Pod для этой проблемы.
в вашем файле pod:
pod 'KeychainAccess', '~> 2.4' //If you are using Swift 2.3 pod 'KeychainAccess' //Defaults to 3.0.1 which is in Swift 3импорт
KeychainAccessмодуль в файле, где вы хотите установить UUID в keychainimport KeychainAccessиспользуйте код ниже, чтобы установить и получить UUID из keychain:
Примечание :BundleId-это ключ, а UUID-значение
var bundleID = NSBundle.mainBundle().bundleIdentifier var uuidValue = UIDevice.currentDevice().identifierForVendor!.UUIDString //MARK: - setVenderId and getVenderId func setVenderId() { let keychain = Keychain(service: bundleID!) do { try keychain.set(venderId as String, key: bundleID!) print("venderId set : key \(bundleID) and value: \(venderId)") } catch let error { print("Could not save data in Keychain : \(error)") } } func getVenderId() -> String { let keychain = Keychain(service: bundleID!) let token : String = try! keychain.get(bundleID!)! return token }
Comments