SecItemAdd总是在iOS 10模拟器

时间:2016-07-19 10:52:03

标签: ios xcode ios10 xcode8

更新:此问题已在Xcode 8.2中修复。 Keychain在模拟器中工作,无需启用钥匙串共享。

在Xcode 8 / iOS 10模拟器中调用SecItemAdd函数时,为什么总是收到错误-34018?

重现步骤

在Xcode 8中创建一个新的单页iOS应用程序项目。 在viewDidLoad(或打开this 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。

配置

在iOS 10模拟器中进行测试时,从Beta 2开始,始终出现在Xcode 8中。

在iOS 9.3模拟器中进行测试时,Xcode 8中不会出现这种情况。

演示

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 and SecItemCopyMatching returns error code -34018 (errSecMissingEntitlement)

9 个答案:

答案 0 :(得分:182)

通过将 Keychain Access Groups 添加到Entitlements文件,我能够在我的应用中解决此问题。我打开了测试应用中功能部分中的 Keychain Sharing 开关,它也适用于我。

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。

答案 1 :(得分:17)

Xcode 8.1 GM Release Notes Apple确认了这个问题并提出了一个更清晰的解决方法:

  

如果您的权利,钥匙串API可能无法在模拟器中运行   file不包含application-identifier的值   权利。 (28338972)解决方法:添加用户定义的构建设置   到您的目标名为ENTITLEMENTS_REQUIRED并将值设置为YES。   这将导致Xcode自动插入   构建时的application-identifier权利。

请注意,根据我的尝试,它仅适用于Xcode 8.1。虽然文本可能会误导您进入构建设置,但您需要做的是将其添加到您的方案中的环境变量中。

enter image description here

Xcode 8.2将解决这个问题:

  

Xcode 8.2 beta中已解决 - IDE Keychain API正常工作   模拟器。 (28338972)

答案 2 :(得分:10)

如果您的测试目标没有主机应用,则会发生这种情况。修复

  1. 添加虚拟主机应用:enter image description here

  2. 启用自动代码签名并添加团队:

  3. enter image description here

    1. 启用功能中的钥匙串共享
    2. enter image description here

答案 3 :(得分:5)

我在使用电子邮件签名,创建新用户或使用firebase注销时遇到错误。

错误是:

  

firauth错误域代码17995

我打开了测试应用中功能部分的Keychain Sharing开关,它也适用于我。

答案 4 :(得分:4)

我一直在寻找一种不使用Keychain共享的解决方案,因为这不是我想要的功能。 The developer forum似乎从EvergreenCoder有一个很好的工作,你可以限制只有iOS 10模拟器(因为这似乎是唯一受影响的模拟器)。从帖子:

  

问题似乎是必须至少有一个权利,以便Xcode正确地将“应用程序标识符”的内容添加到构建的应用程序中。这就是为什么钥匙串共享似乎是一个解决方案,但它只是间接地如此:任何其他权利似乎都可以正常工作。

您可以像这样创建+0

.plist

并在

中的Build Settings下提供该文件的路径

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-/ <plist version="1.0"> <dict> <key>get-task-allow</key> <true/> </dict> </plist>

如帖子所述,此权利只允许附加调试器。

答案 5 :(得分:1)

我遇到了类似的问题,但是当我尝试在设备上运行时遇到-34018错误。我在使用iOS 10.1的Sierra上使用XCode 8.1。我在一个团队工作,当我们在项目设置中切换到“自动管理签名”时突然遇到了这个问题。当我关闭它并手动选择我的个人资料时,一切正常。我最终不得不从我的钥匙串中删除我的开发人员证书,然后重新选择“自动管理签名”。在下一个版本中,它为我生成了一个新的签名证书,现在一切正常。我仍然不确定导致问题的原因是因为其他证书在手动选择时工作正常,但在由XCode管理时则不行。希望这有助于阻止其他人长时间头痛。

答案 6 :(得分:0)

在启用功能中的钥匙串共享后,它可以正常工作。

答案 7 :(得分:0)

我能够在Xcode 11中解决此问题,而无需进行任何权利调整。

我只是将一个新的应用程序目标添加到了我的框架项目MyFrameworkTestsHostApp中。

然后,我选择MyFrameworkTests目标,并将其主机应用程序选择为MyFrameworkTestsHostApp。

答案 8 :(得分:0)

有3个步骤可以快速解决此问题。

  1. 打开项目功能中的钥匙串共享。
  2. 选择使用配置文件自动配置
  3. 确保将自定义权利选项设置为Entitlement.plist。

这会神奇