Значение записи цепочки ключей iOS приводит к коду ошибки -34018
У меня есть приложение для iOS, которое хранит некоторую конфиденциальную информацию в цепочке для ключей. При записи значений в связку ключей я получаю код ошибки -34018.
В настоящее время я использую класс Apple KeyChainItemWrapper для iOS.
Обе следующие строки кода получают один и тот же код ошибки.
OSStatus res1 = SecItemCopyMatching((__bridge CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes);
OSStatus res = SecItemUpdate((__bridge CFDictionaryRef)updateItem, (__bridge CFDictionaryRef)tempCheck);
Эта проблема возникает не каждый раз, но периодически. Как только я получаю эту ошибку, я больше не могу записывать какие-либо значения в цепочку для ключей.
Я напечатал описание ошибки так:
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:res userInfo:nil];
и вот что распечатывает ошибка:
Error: Error Domain=NSOSStatusErrorDomain Code=-34018 "The operation couldn’t be completed. (OSStatus error -34018.)"
8 ответов
Если кто-то вернется сюда с этой ошибкой и XCode8 с iOS10, вероятно, вам нужно включить KeyChain Share на вкладке Capabilities
:
Похоже, это ошибка в связке ключей, которая появляется только при запуске приложения из xcode. Смотрите здесь: https://github.com/soffes/sskeychain/issues/52
Мы много отлаживали, и кажется, что проблема с доступом к цепочке для ключей, когда приложение запускается из фона. Это происходит только с отладчиком (т.е. при запуске из Xcode). Мы считаем, что в нашем случае проблема может быть связана с тем, что отладчик поддерживает приложение, даже если оно должно быть уничтожено ОС. На самом деле мы попытались запустить приложение, а затем перевести его в фоновый режим и запустить много других приложений, занимающих оперативную память. В отладчике ошибка возникла при возобновлении приложения из фона, а без отладчика - нет (мы выполнили не менее 10 тестов каждый).
Как уже упоминалось, это ошибка брелка, о которой Apple знает и знает с середины 2015 года.
Однако по состоянию на 22 марта 2016 года Apple заявила:
Мы считаем, что эти проблемы были решены в iOS 9.3.
iOS 9.3 была выпущена 21 марта 2016 года.
Смотрите ветку: https://forums.developer.apple.com/thread/4743
Чтобы процитировать ответ сотрудника Apple:
22 марта 2016 г. 3:28
Хорошо, вот последний. Это сложная проблема с несколькими возможными причинами:
Некоторые случаи проблемы вызваны неправильной подписью приложения. Вы можете легко отличить этот случай, потому что проблема воспроизводима на 100%.
Некоторые случаи этой проблемы вызваны ошибкой в том, как iOS поддерживает разработку приложений (см. 23,991,853). Отладка этого была осложнена тем фактом, что другая ошибка в ОС (т. 23,770 418) скрывала его действие, то есть проблема возникала только тогда, когда устройство находилось под давлением памяти.
Мы считаем, что эти проблемы были решены в iOS 9.3.
Мы подозреваем, что может быть еще больше причин этой проблемы.
Итак, если вы видите эту проблему на пользовательском устройстве (с которым не общался Xcode), работающем под управлением iOS 9.3 или более поздней версии, пожалуйста, сообщите об этом в отчете об ошибке. Попробуйте включить системный журнал устройства в свой отчет об ошибках (я понимаю, что это может быть сложно при работе с клиентскими устройствами; один из вариантов - попросить клиента установить Apple Configurator, который позволяет ему просматривать системный журнал). И если вы подаете ошибку, пожалуйста, напишите свой номер ошибки, просто для записи.
От имени Apple я хотел бы поблагодарить всех за их усилия по оказанию помощи в поиске этой довольно ужасной проблемы.
Поделитесь и наслаждайтесь
Это задержало меня на 2 часа, прежде чем я нашел быстрое "исправление" - перезагрузка устройства iOS
Цитата из обсуждения на http://forums.developer.apple.com/thread/4743,
От пользователя littledetails
Как уже сообщали другие, эту загадочную ошибку связки ключей легче всего заметить при запуске через Xcode с подключенным отладчиком. Как только ошибка начинает возникать, цепочка для ключей, кажется, не исправляет себя независимо от давления памяти, пока один не перезагружает устройство.
Когда я перезагрузил свое устройство, ошибка исчезла, что позволило мне продолжить тестирование. Не уверен, что еще делать. В моей ситуации переход на NSUserDefaults или другое хранилище был невозможен.
Одним из способов обойти эту проблему с помощью цепочки для ключей является использование dispatch_async для запуска приложения. Это работает, когда приложение открывается из фона. Также убедитесь, что у вас есть kSecAttrAccessibleAfterFirstUnlock
настройка доступности на связке ключей.
dispatch_async(dispatch_get_main_queue(), ^{
// save/write to keychain
})
Я использую классы GenericKeychain от Apple:
https://developer.apple.com/library/content/samplecode/GenericKeychain/Introduction/Intro.html
struct KeychainConfiguration {
static let serviceName = "MyAppService"
/*
Specifying an access group to use with `KeychainPasswordItem` instances will create items shared accross both apps.
For information on App ID prefixes, see:
https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/AppID.html
and:
https://developer.apple.com/library/ios/technotes/tn2311/_index.html
*/
// static let accessGroup = "[YOUR APP ID PREFIX].com.example.apple-samplecode.GenericKeychainShared"
/*
Not specifying an access group to use with `KeychainPasswordItem` instances
will create items specific to each app.
*/
static let accessGroup: String? = nil
}
В этом файле я указывал мою пользовательскую группу доступа в этой строке static let accessGroup = "[ВАШ ПРИЛОЖЕНИЕ ИД APP].com.example.apple-samplecode.GenericKeychainShared"
После возвращения в статический пусть accessGroup: String? = ноль проблема исчезла:)
Убедитесь, что совместное использование цепочки для ключей должно быть включено в разделе Возможности в проекте Target
В моем случае файл App_Name.entitlements имеет другой идентификатор пакета, чем мой пакетный идентификатор проекта. Итак, я меняю идентификатор пакета в файле App_Name.entitlements с идентификатором пакета моего проекта. Например, предположим, что ваш пакетный идентификатор проекта com.Apple.testApp, а затем получил
- Ключ открытия файла App_Name.entitlements Ключ групп доступа к цепочке ключей, который имеет тип массива.
- В элементе item0 задайте значение идентификатора пакета вашего проекта, например:- $(AppIdentifierPrefix)com.Apple.testAp.
Согласно ответу @iCaramba. Я нашел обходной путь:
- Остановите задачу, чтобы убить приложение (если вы уже запускаете приложение)
- Запустите приложение на вашем устройстве вручную. НЕ используйте Xcode
- Используйте XCode для повторного запуска приложения