SecItemAdd 在 iOS 10 模拟器的 Xcode 8 中总是返回错误 -34018
Posted
技术标签:
【中文标题】SecItemAdd 在 iOS 10 模拟器的 Xcode 8 中总是返回错误 -34018【英文标题】:SecItemAdd always returns error -34018 in Xcode 8 in iOS 10 simulator 【发布时间】:2016-11-22 05:26:50 【问题描述】:更新:此问题已在 Xcode 8.2 中修复。钥匙串在模拟器中工作,无需启用钥匙串共享。
为什么我在 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)
【问题讨论】:
这似乎仍然是 Xcode 8 GM 中的一个问题。很高兴看到 Apple 仍处于领先地位... 我真的在挖掘你的控制台日志:-) 该问题已在 Xcode 8.2 中修复,但在 Xcode 9.0 中又出现了! 【参考方案1】:通过将 钥匙串访问组 添加到权利文件,我能够在我的应用程序中解决此问题。我在您的测试应用的 Capabilities 部分中打开了 Keychain Sharing 开关,它也对我有用。
要添加到权利的项目:
<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 上使用 8b5 进行测试时也不会发生苹果手机)。我注意到功能中的推送通知需要修复(即按下按钮)并同时打开钥匙串共享,不幸的是。然后应用程序不再收到错误。再次关闭关闭 Keychain Sharing后,它仍然有效! 我使用钥匙串作为测试目标,但它失败了 - 我该如何解决这个问题? (因为测试目标中没有能力) @SamJarman 我也有这个问题。我刚刚进入测试目标的构建设置并取消设置权利字段。之后工作正常。 此解决方案适用于应用目标。不幸的是,我正在开发一个使用 KeychainSwift 的 Swift 框架,由于该错误,该框架不再构建。在框架目标中,我无法添加权利文件 afaik。有人知道这种情况的解决方法吗? @JanNash,这是我设法使测试工作的方法evgenii.com/blog/testing-a-keychain-library-in-xcode【参考方案2】:在Xcode 8.1 GM Release NotesApple 中承认了该问题并提出了更简洁的解决方法:
如果您的权利,钥匙串 API 可能无法在模拟器中工作 文件不包含应用程序标识符的值 权利。 (28338972) 解决方法:添加用户定义的构建设置 到名为 ENTITLEMENTS_REQUIRED 的目标并将值设置为 YES。 这将导致 Xcode 自动插入一个 构建时的应用程序标识符权利。
请注意,根据我的尝试,它仅适用于 Xcode 8.1。尽管文本可能会误导您进入构建设置,但您需要将其添加到您的环境变量中,在您的方案中。
Xcode 8.2 将解决这个问题:
在 Xcode 8.2 beta 中已解决 - IDE Keychain API 在 模拟器。 (28338972)
【讨论】:
@Tiago 在 iOS 10.1 模拟器上的 Xcode 8.1 中,发行说明中的这个解决方法是否仍然适用于您?我尝试添加此设置(既作为目标上的用户定义设置,也作为方案中的环境变量),在 iOS 10.1 模拟器上运行时,我仍然得到 -34018 返回值。 @guywithmazda,这里也一样。仍然得到 -34018 并尝试了构建设置和环境变量。 对我不起作用,无论是在构建设置中,还是在 Sierra 上的 Xcode 8.1 (8B62) 中作为方案的环境变量。我错过了什么吗? 我使用的是 Xcode 8.2.1,这个问题仍然可以重现。另外,我的问题是如果我没有宿主应用程序,并且我正在创建框架目标,那么如何解决这个问题? 这个问题仍然会影响框架目标的单元测试,因为在这种情况下,测试主机存根需要授权。我们知道这个问题,但如果它对您来说是一个障碍,请提交一个重复的错误。【参考方案3】:如果您的测试目标没有宿主应用程序,则可能会发生这种情况。修复
添加虚拟主机应用:
启用自动代码签名并添加团队:
-
在功能中启用钥匙串共享
【讨论】:
【参考方案4】:我在使用电子邮件签名、创建新用户或使用 Firebase 注销时遇到错误。
错误是:
firauth 错误域代码 17995
我在您的测试应用的“功能”部分打开了钥匙串共享开关,它也对我有用。
【讨论】:
【参考方案5】:我一直在寻找不使用钥匙串共享的解决方案,因为这不是我想要的功能。 The developer forum 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 错误。我在带有 iOS 10.1 的 Sierra 上使用 XCode 8.1。我在一个团队中工作,当我们在项目设置中切换到“自动管理签名”时突然遇到了这个问题。当我关闭它并手动选择我的个人资料时,一切正常。我最终不得不从我的钥匙串中删除我的开发者证书,然后重新选择“自动管理签名”。在下一次构建中,它为我生成了一个新的签名证书,现在一切正常。我仍然不确定是什么导致了这个问题,因为其他证书在手动选择时工作正常,但在由 XCode 管理时却不行。希望这有助于停止对其他人长达数小时的头痛。
【讨论】:
【参考方案7】:我能够在 Xcode 11 中解决此问题,而无需进行任何权利调整。
我只是在我的框架项目中添加了一个名为 MyFrameworkTestsHostApp 的新应用目标。
然后我选择了 MyFrameworkTests 目标并将其主机应用程序选择为 MyFrameworkTestsHostApp。
【讨论】:
【参考方案8】:开启钥匙串共享功能后即可使用。
【讨论】:
【参考方案9】:有 3 个步骤可以快速解决此问题。
-
在您的项目功能中启用钥匙串共享。
使用配置文件选择自动配置
确保您的自定义权利选项设置为 Entitlement.plist。
这会变魔术
【讨论】:
以上是关于SecItemAdd 在 iOS 10 模拟器的 Xcode 8 中总是返回错误 -34018的主要内容,如果未能解决你的问题,请参考以下文章
SecItemAdd 和 SecItemCopyMatching 返回错误代码 -34018 (errSecMissingEntitlement)
OSX 10.10 Yosemite 上的 iOS 6.1 模拟器
Xcode 10.2 无法在 iOS < 10 的模拟器上运行应用程序