KeychainWrapperItem перестал работать в iOS 7.1

Я недавно установил симулятор iOS 7.1 и новый Xcode 5.1. Мое приложение работало в iOS 7 нормально. Я использую класс KeychainItemWrapper от Apple. После обновления произошел сбой со следующим сообщением:

*** Assertion failure in -[KeychainItemWrapper writeToKeychain]

В частности, в строке 299:

NSAssert( result == noErr, @"Couldn't update the Keychain Item." );

Ошибка слышна -25300 (errSecItemNotFound)

Я указал группу доступа Keychain в моем файле прав. Эта ошибка произошла только в симуляторе iOS 7.1, а не на реальном iPhone или симуляторе 7.0.

Кто-нибудь знает, что изменилось с Keychain в 7.1?

2 ответа

Решение

Ну, KeychainItemWrapper - старая реализация, полная ошибок. Я бы порекомендовал использовать другую обертку или написать свою.

При этом у меня было много ошибок, но не этой. По сути, при сохранении он проверяет, что ваш элемент уже находится в цепочке для ключей, чтобы добавить его или просто обновить. Здесь эта проверка возвращает true, даже если элемент совсем другой, поэтому он не может обновляться, потому что SecItemUpdate считает, что его не существует.

Что вам нужно сделать, это сбросить цепочку для ключей, у вас есть два варианта для этого:

  • На симуляторе Меню Симулятор-> Сбросить контент и настройки

  • Запустите этот фрагмент где-нибудь в вашем коде:

Основываясь на ответе Vegard, здесь можно сбросить брелок для iPhone-приложения

-(void)resetKeychain {
     [self deleteAllKeysForSecClass:kSecClassGenericPassword];
     [self deleteAllKeysForSecClass:kSecClassInternetPassword];
     [self deleteAllKeysForSecClass:kSecClassCertificate];
     [self deleteAllKeysForSecClass:kSecClassKey];
     [self deleteAllKeysForSecClass:kSecClassIdentity];
}

-(void)deleteAllKeysForSecClass:(CFTypeRef)secClass {
     NSMutableDictionary* dict = [NSMutableDictionary dictionary];
    [dict setObject:(__bridge id)secClass forKey:(__bridge id)kSecClass];
    OSStatus result = SecItemDelete((__bridge CFDictionaryRef) dict);
     NSAssert(result == noErr || result == errSecItemNotFound, @"Error deleting keychain data (%ld)", result);
}

Брелок продолжает работать под iOS 7.1. Ваша проблема связана с самим симулятором. Насколько мне известно, симулятор не позволяет хранить определенные ключи, и это совместимо между iOS 7.0 и iOS 7.1.

Если вы запустите приложение на реальном устройстве, сбой исчезнет.

Другие вопросы по тегам