我有一个iOS应用程序,可以在钥匙串中存储一些敏感信息。 在将值写入钥匙串时,我收到错误代码-34018。
我目前正在使用Apple的iOS KeyChainItemWrapper类。
以下两行代码都会收到相同的错误代码。
OSStatus res1 = SecItemCopyMatching((__bridge CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes);
OSStatus res = SecItemUpdate((__bridge CFDictionaryRef)updateItem, (__bridge CFDictionaryRef)tempCheck);
此问题不是每次都会发生,而是间歇性地发生。一旦我收到此错误,我就无法再将任何值写入钥匙串。
我打印了错误说明,如下:
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:res userInfo:nil];
这就是错误打印出来的内容:
Error: Error Domain=NSOSStatusErrorDomain Code=-34018 "The operation couldn’t be completed. (OSStatus error -34018.)"
答案 0 :(得分:34)
似乎这是Keychain中的一个错误,它只会在您从xcode启动应用时出现。见这里:https://github.com/soffes/sskeychain/issues/52
我们调试了很多,而且在访问钥匙串时似乎是一个问题 该应用程序从后台启动。这只发生在 调试器(即从Xcode启动时)。我们认为这个问题 可能与我们的情况有关,调试器使应用程序保持活跃状态 即使它应该被操作系统杀死。事实上,我们尝试过运行 应用程序然后把它放在后台并启动许多其他应用程序占用 内存。使用调试器时,从应用程序恢复应用程序时出现错误 背景,虽然没有调试器,但它没有(我们至少运行过 每项10项测试。
答案 1 :(得分:26)
答案 2 :(得分:4)
正如其他人所提到的,这是一个Keychain错误,这是Apple至少知道并且至少从2015年中期就已经知道的错误。
截至2016年3月22日,Apple已表示:
我们相信这些问题已在iOS 9.3中得到解决。
iOS 9.3于2016年3月21日发布。
见线程:https://forums.developer.apple.com/thread/4743
引用Apple员工的回复:
2016年3月22日上午3:28
好的,这是最新的。这是一个复杂的问题,有多种可能的原因:
问题的某些情况是由不正确的应用签名引起的。您可以轻松区分这种情况,因为问题是100%可重现的。
问题的某些实例是由iOS支持应用程序开发的错误引起的(r.23,991,853)。由于操作系统中的另一个错误(r.23,770,418)掩盖了它的影响,这个问题很复杂,这意味着当设备处于内存压力下时问题才会出现。
我们相信这些问题已在iOS 9.3中得到解决。
我们怀疑这个问题可能还有更多原因。
因此,如果您在运行iOS 9.3或更高版本的用户设备(Xcode尚未与之交谈)上看到此问题,请提交有关它的错误报告。尝试将设备系统日志包含在您的错误报告中(我意识到在处理客户设备时可能会非常棘手;一种选择是要求客户安装Apple Configurator,这样他们就可以查看系统日志)。如果您确实提交了错误,请发布您的错误号,仅供记录。
我代表Apple感谢大家为帮助追查这个相当可怕的问题所做的努力。
分享并享受
答案 3 :(得分:3)
这让我筋疲力尽了2个小时才发现了一个快速的"修复" - 重启iOS设备
http://forums.developer.apple.com/thread/4743的讨论引用,
来自用户 littledetails
正如其他人所报道的那样,当通过附带调试器的Xcode启动时,这个神秘的钥匙串错误最容易被观察到。一旦错误开始发生,无论内存压力,钥匙串都无法正确显示,直到重新启动设备。
当我重新启动设备时,错误消失了,让我继续测试。不知道还能做什么。在我的情况下,不可能转移到NSUserDefaults或其他一些存储解决方案。
答案 4 :(得分:2)
使用钥匙串解决此问题的一种方法是使用dispatch_async来启动应用程序。这可以在从后台打开应用程序时起作用。另外,请确保钥匙串上有kSecAttrAccessibleAfterFirstUnlock
辅助功能设置。
dispatch_async(dispatch_get_main_queue(), ^{
// save/write to keychain
})
答案 5 :(得分:1)
我正在使用Apple的GenericKeychain类:
struct KeychainConfiguration {
static let serviceName = "MyAppService"
/*
Specifying an access group to use with `KeychainPasswordItem` instances will create items shared accross both apps.
For information on App ID prefixes, see:
https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/AppID.html
and:
https://developer.apple.com/library/ios/technotes/tn2311/_index.html
*/
// static let accessGroup = "[YOUR APP ID PREFIX].com.example.apple-samplecode.GenericKeychainShared"
/*
Not specifying an access group to use with `KeychainPasswordItem` instances
will create items specific to each app.
*/
static let accessGroup: String? = nil
}
在此文件中,我在此行中指定了自定义accessGroup static let accessGroup =&#34; [您的APP ID PREFIX] .com.example.apple-samplecode.GenericKeychainShared&#34; < / p>
返回 static后,让accessGroup:String? = nil 问题消失了。 :)
答案 6 :(得分:0)
根据@ iCaramba的回答。我找到了一个解决方法:
答案 7 :(得分:0)
确保目标项目中功能下的钥匙串共享必须。
在我的情况下,App_Name.entitlements文件具有与我的项目包ID不同的包ID。因此,从我的项目包ID开始,我更改了App_Name.entitlements文件中的包ID。 例如,假设您的项目捆绑包ID为com.Apple.testApp,然后转到