SecItemAdd всегда возвращает ошибку -34018 в Xcode 8 в симуляторе iOS 10
Обновление: эта проблема исправлена в Xcode 8.2. Брелок работает в симуляторе без возможности совместного использования ключей.
Почему я всегда получаю ошибку -34018 при вызове функции SecItemAdd
в симуляторе Xcode 8/iOS 10?
Действия по воспроизведению
Создайте новый проект приложения iOS для одной страницы в Xcode 8. Запустите следующий код в viewDidLoad
(или откройте этот проект Xcode).
let itemKey = "My key"
let itemValue = "My secretive bee 🐝"
// Remove from Keychain
// ----------------
let queryDelete: [String: AnyObject] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: itemKey as AnyObject
]
let resultCodeDelete = SecItemDelete(queryDelete as CFDictionary)
if resultCodeDelete != noErr {
print("Error deleting from Keychain: \(resultCodeDelete)")
}
// Add to keychain
// ----------------
guard let valueData = itemValue.data(using: String.Encoding.utf8) else {
print("🐣🐣🐣🐣🐣🐣🐣🐣🐣🐣 Error saving text to Keychain")
return
}
let queryAdd: [String: AnyObject] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: itemKey as AnyObject,
kSecValueData as String: valueData as AnyObject,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
]
let resultCode = SecItemAdd(queryAdd as CFDictionary, nil)
if resultCode != noErr {
print("🐝🐝🐝🐝🐝🐝🐝🐝🐝 Error saving to Keychain: \(resultCode).")
} else {
print("🍀🍀🍀🍀🍀🍀🍀🍀🍀 Saved to keychain successfully.")
}
Ожидаемые результаты
Пункт добавляется в брелок.
Фактические результаты
Функция SecItemAdd возвращает следующий код ошибки: -34018
.
Версия
Xcode версии 8.1 (8B62), macOS Sierra 10.12.1.
конфигурация
Всегда происходит в Xcode 8 с Beta 2 при тестировании в симуляторе iOS 10.
Не происходит в Xcode 8 при тестировании в симуляторе iOS 9.3.
демонстрация
https://dl.dropboxusercontent.com/u/11143285/2016/07/KeychainBugDemo.zip
Рекомендации
Радар: https://openradar.appspot.com/27422249
Форумы Apple для разработчиков: https://forums.developer.apple.com/message/179846
Эта проблема отличается от следующей записи, потому что она последовательно возникает в Xcode 8. SecItemAdd и SecItemCopyMatching возвращают код ошибки -34018 (errSecMissingEntitlement)
Ответы
Ответ 1
Мне удалось обойти это в своем приложении, добавив Группы доступа Keychain в файл Права. Я включил переключатель Keychain Sharing в разделе Capabilities в тестовом приложении, и он работает и для меня.
![Screenshot of turning on the switch]()
Элемент, который нужно добавить к правам:
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.evgenii.KeychainBugDemo</string>
</array>
Я только пробовал это на macOS Sierra (10.12), поэтому я не уверен, будет ли он работать для вас 10.11.5.
Ответ 2
В Xcode 8.1 Примечания к выпуску GM Apple признала эту проблему и предложила более эффективный способ:
API-интерфейсы Keychain могут не работать в Simulator, если ваш файл прав не содержит значения для права на идентификатор приложения. (28338972) Временное решение: добавьте заданную пользователем настройку сборки для вашей цели с именем ENTITLEMENTS_REQUIRED и установите для нее значение YES. Это приведет к тому, что Xcode будет автоматически вставлять права приложения-идентификатора при создании.
Обратите внимание, что из того, что я пробовал, он работает только в Xcode 8.1. Хотя текст может ввести вас в заблуждение в настройке сборки, вам нужно добавить это в свои переменные среды в свою схему.
![enter image description here]()
Xcode 8.2 решит следующее:
Решено в Xcode 8.2 бета - IDE Keychain API работают правильно в Simulator. (28338972)
Ответ 3
Это может произойти, если у вас есть тестовая цель, у которой нет хост-приложения. Чтобы исправить
![введите описание изображения здесь]()
- Включить обмен ключами в возможностях
![введите описание изображения здесь]()
Ответ 4
У меня возникла ошибка при подписании с электронной почтой, создании нового пользователя или выводе с использованием firebase.
Ошибка:
код домена ошибки firauth 17995
Я включил переключатель Keychain Sharing в разделе Capabilities в тестовом приложении, и он работает и для меня.
Ответ 5
Я искал решение, которое не использовало совместное использование Keychain, поскольку это была не функция, которую я искал. Форум разработчиков Кажется, у EverGreenCoder хорошая работа, которую вы можете ограничить только симулятором iOS 10 (поскольку это, кажется, единственный затронутый имитатор). Из сообщения:
Кажется, что проблема заключается в том, что для того, чтобы Xcode должным образом добавлял привязку "идентификатор приложения" к встроенному приложению, должно быть хотя бы одно право. Вот почему совместное использование ключей - это решение, но это только косвенно: любое другое право, похоже, работает нормально.
Вы можете создать .plist
так:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-/
<plist version="1.0">
<dict>
<key>get-task-allow</key>
<true/>
</dict>
</plist>
и укажите путь к этому файлу в разделе "Настройки сборки" в
Code Signing->Debug->Simulater iOS 10 SDK->($SRCROOT)/your-path-to-file
Как указано в сообщении, это право позволяет просто подключить отладчик.
Ответ 6
У меня была аналогичная проблема, хотя при попытке запустить на устройстве я получал ошибку -34018. Я использую XCode 8.1 для Sierra с iOS 10.1. Я работаю над командой и вдруг столкнулся с этой проблемой, когда переключился на "Автоматическое управление подписью" в настройках проекта. Когда я отключу это и вручную выберите свой профиль, все будет хорошо. В итоге мне пришлось удалить свой сертификат разработчика из моей связки ключей, а затем повторно выбрать "Автоматически управлять подписью". На следующей сборке он создал для меня новый сертификат подписи, и теперь все работает отлично. Я все еще не уверен, что вызвало проблему, поскольку другой сертификат работал нормально при выборе вручную, но не при управлении XCode. Надеюсь, что это поможет остановить чашу головной боли для кого-то другого.
Ответ 7
Он работает после включения совместного использования ключей в возможностях.