SecItemAdd始终在iOS 10模拟器的Xcode 8中返回错误-34018


103

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

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

重现步骤

在Xcode 8中创建一个新的Single page iOS应用程序项目。在中运行以下代码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。

组态

自从Beta 2在iOS 10模拟器中进行测试时,始终会在Xcode 8中发生。

在iOS 9.3模拟器中进行测试时,在Xcode 8中不会发生。

演示版

https://dl.dropboxusercontent.com/u/11143285/2016/07/KeychainBugDemo.zip

参考资料

雷达:https//openradar.appspot.com/27422249

苹果开发者论坛:https : //forums.developer.apple.com/message/179846

此问题与以下文章不同,因为它在Xcode 8中始终存在。SecItemAdd和SecItemCopyMatching返回错误代码-34018(errSecMissingEntitlement)


8
在Xcode 8 GM中,这似乎仍然是一个问题。很高兴看到Apple仍然处于领先地位……
Nicholas Harlen

1
对我来说一样,还是这个错误
Kostiantyn Koval

我真的在挖掘您的控制台日志:-)
Nicolas Miari

该问题已在Xcode 8.2中修复,但已在Xcode 9.0中恢复!
阿迪尔·侯赛因

Answers:


183

通过将“ 钥匙串访问组”添加到“权利”文件中,我能够在我的应用程序中解决此问题。我在测试应用程序的“ 功能”部分中打开了“ 钥匙串共享”开关,它也对我有用。

打开开关的屏幕截图

要添加到权利中的项目:

<key>keychain-access-groups</key>
<array>
    <string>$(AppIdentifierPrefix)com.evgenii.KeychainBugDemo</string>
</array>

我仅在macOS Sierra(10.12)上尝试过此操作,因此我不确定它是否在10.11.5上适用。


同样,这里只是我当前正在使用Xcode 8 beta 5(使用iOS 10模拟器。以前的beta没有出现问题。在真实的iOS 9 iPhone上使用8b5测试时也不会发生)。我注意到,不幸的是,“功能中的推送通知”需要修复(即按下按钮),并且还需要打开“钥匙串共享”。然后,该应用不再收到错误。打开后关闭再次钥匙扣共享,它仍然有效!
斯特凡

2
我将钥匙串用作测试目标,但失败了-我该如何解决?(由于测试目标没有功能)
Sam Jarman

1
@SamJarman我也有这个问题。我只是进入测试目标的构建设置并取消设置权利字段。之后工作正常。
约旦邦多

3
该解决方案适用于App Target。不幸的是,我正在使用使用KeychainSwift的Swift框架,由于该错误,该框架不再构建。在框架目标中,我无法添加权利文件afaik。有人知道这种情况的解决方法吗?
Jan Nash

5
@JanNash,这是我设法使测试工作进行起来的方式evgenii.com/blog/testing-a-keychain-library-in-xcode
Evgenii

17

Xcode 8.1 GM发行说明中, Apple确认了该问题,并提出了一种更清洁的解决方法:

如果您的权利文件中不包含应用程序标识符权利的值,则钥匙串API可能无法在Simulator中工作。(28338972)解决方法:将用户定义的构建设置添加到名为ENTITLEMENTS_REQUIRED的目标,并将其值设置为YES。这将导致Xcode在构建时自动插入应用程序标识符授权。

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

在此处输入图片说明

Xcode 8.2将解决此问题:

Xcode 8.2 beta中已解决-IDE钥匙串API在Simulator中可以正常工作。(28338972)


1
@Tiago在iOS 10.1模拟器上的Xcode 8.1中,发行说明中的​​此变通办法是否仍对您有用?我尝试添加此设置(既作为目标上的用户定义设置,又作为方案中的环境变量),并且在iOS 10.1模拟器上运行时,我仍然得到-34018返回值。
guywithmazda

3
@guywithmazda,这里也是。仍然得到-34018并尝试了构建设置和环境变量。
keithbhunter 2016年

不适用于我,无论是在构建设置中还是在Sierra上的Xcode 8.1(8B62)中都不作为方案的环境变量。我想念什么吗?
Evgenii

4
我正在使用Xcode 8.2.1,并且此问题仍然可以重现。另外,我的问题是,如果我没有主机应用程序,并且正在创建Framework目标,那么如何解决此问题?
DShah

2
此问题仍会影响Framework目标的单元测试,因为在这种情况下,将是需要授权的测试主机存根。我们已经知道了这个问题,但是如果对您不利,请提交重复的错误。
russbishop

10

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

  1. 添加一个虚拟主机应用程序: 在此处输入图片说明

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

在此处输入图片说明

  1. 启用功能中的钥匙串共享

在此处输入图片说明


5

使用电子邮件签名,创建新用户或使用Firebase注销时出现错误。

错误是:

firauth错误域代码17995

我在测试应用程序的“功能”部分中打开了“钥匙串共享”开关,它也对我有用。


4

我一直在寻找不使用钥匙串共享的解决方案,因为那不是我想要的功能。开发人员论坛似乎在EvergreenCoder方面有不错的工作,您可以将范围限制为仅iOS 10模拟器(因为这似乎是唯一受影响的模拟器)。从帖子:

问题似乎在于,至少必须有一项权利,Xcode才能将“ application-identifier”实体正确地添加到已构建的应用程序中。这就是为什么钥匙串共享似乎是一种解决方案,但仅是间接的原因:任何其他权利似乎都可以正常工作。

您可以这样创建.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

如文章中所述,此权利仅允许附加调试器。


1

我遇到了类似的问题,尽管尝试在设备上运行时出现-34018错误。我正在iOS 10.1的Sierra上使用XCode 8.1。我在一个团队中工作,当我们在项目设置中切换为“自动管理签名”时,突然遇到了这个问题。当我关闭此功能并手动选择我的个人资料时,一切正常。我最终不得不从钥匙串中删除开发人员证书,然后重新选择“自动管理签名”。在下一个版本中,它为我生成了一个新的签名证书,并且现在一切正常。我仍然不确定是什么引起了这个问题,因为手动选择其他证书时效果很好,但是当由XCode管理时却不能。希望这可以帮助其他人避免一个小时的头痛。


1

我无需任何权利调整即可在Xcode 11中解决此问题。

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

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


0

在启用功能中的钥匙串共享后,它才能工作。


0

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

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

这会做魔术

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.