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

Это может произойти, если у вас есть тестовая цель, у которой нет хост-приложения. Чтобы исправить

  • добавить фиктивное хост-приложение: введите описание изображения здесь

  • Включить автоматическую подписание кода и добавить команду:

введите описание изображения здесь

  1. Включить обмен ключами в возможностях

введите описание изображения здесь

Ответ 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

Он работает после включения совместного использования ключей в возможностях.