有时,当我在Xcode上运行设备上的应用程序时,我会尝试访问密钥链但由于错误-34018而失败.这与任何记录的钥匙串错误代码都不匹配,并且无法一致地再现.(可能有30%的时间发生,我不清楚为什么会发生这种情况).使调试这个问题变得非常困难的原因是完全缺乏文档.知道是什么导致这个以及如何解决它?我正在使用Xcode 5并在设备上运行iOS 7.0.4.
这里有一个公开的问题:https://github.com/soffes/sskeychain/issues/52
编辑:每个请求添加钥匙串访问代码
我正在使用该SSKeychain
库与钥匙串连接.这是片段.
#define SERVICE @"default" @implementation SSKeychain (EXT) + (void)setValue:(NSString *)value forKey:(NSString *)key { NSError *error = nil; BOOL success = NO; if (value) { success = [self setPassword:value forService:SERVICE account:key error:&error]; } else { success = [self deletePasswordForService:SERVICE account:key error:&error]; } NSAssert(success, @"Unable to set keychain value %@ for key %@ error %@", value, key, error); if (!success) { LogError(@"Unable to set value to keychain %@", error); } LogTrace(@"Will set keychain account %@. is to nil? %d", key, value == nil); if (value == nil) LogWarn(@"Setting keychain %@ to nil!!!", key); } + (NSString *)valueForKey:(NSString *)key { NSError *error = nil; NSString *value = [self passwordForService:SERVICE account:key error:&error]; if (error && error.code != errSecItemNotFound) { NSAssert(!error, @"Unable to retrieve keychain value for key %@ error %@", key, error); LogError(@"Unable to retrieve keychain value for key %@ error %@", key, error); } return value; } + (BOOL)removeAllValues { LogInfo(@"Completely Reseting Keychain"); return [[self accountsForService:SERVICE] all:^BOOL(NSDictionary *accountInfo) { return [self deletePasswordForService:SERVICE account:accountInfo[@"acct"]]; }]; } @end
绝大部分时间都很好.有时我会遇到断言故障,我无法写入或读取钥匙串,导致严重的断言失败.
尝试从Xcode 启动应用程序时禁用所有断点.您可以在之后启用它们.
(上述解决方法均不适用于我)
iOS 10/XCode 8修复:
添加KeyChain权利,转到项目设置 - >功能 - >钥匙串共享 - >添加钥匙串组+打开
来自Apple的答案:
更新:我们终于能够在iOS 8.3上重现-34018错误.这是确定根本原因然后提出修复的第一步.
像往常一样,我们无法承诺发布时间表,但这已经影响了许多开发人员,我们真的想要解决这个问题.
之前我建议在应用程序中添加一个小延迟:didFinishLaunchingWithOptions和applicationDidBecomeActive:在访问钥匙串之前作为变通方法.但是,这实际上似乎没有帮助.这意味着除了重新启动应用程序之外,目前还没有已知的解决方法.
这个问题似乎与内存压力有关,因此在处理内存警告方面可能更积极一些可能会缓解这个问题
https://forums.developer.apple.com/thread/4743#14441
UPDATE
好的,这是最新的.
这是一个复杂的问题,有多种可能的原因:
某些问题的实例是由不正确的应用程序签名引起的.您可以轻松区分这种情况,因为问题是100%可重现的.
问题的一些实例是由iOS支持应用程序开发的错误引起的(r.23,991,853).由于操作系统中的另一个错误(r.23,770,418)掩盖了它的影响,这个问题很复杂,这意味着当设备处于内存压力时问题才会出现.我们相信这些问题已在iOS 9.3中得到解决.
我们怀疑这个问题可能还有更多原因.
因此,如果您在运行iOS 9.3或更高版本的用户设备(Xcode尚未与之交谈)上看到此问题,请提交有关它的错误报告.尝试将设备系统日志包含在您的错误报告中(我意识到在处理客户设备时可能会非常棘手;一种选择是要求客户安装Apple Configurator,这样他们就可以查看系统日志).如果您确实提交了错误,请发布您的错误号,仅供记录.
我代表Apple感谢大家为帮助追查这个相当可怕的问题所做的努力.分享和享受
https://forums.developer.apple.com/thread/4743#126088
检查源代码后.我注意到,钥匙串功能是通过在其自己的进程中运行的安全守护程序访问的(与应用程序进程分开).
您的应用程序和安全流程通过称为XPC的技术"一起"进行"交谈" .
如有必要,securityd将通过XPC着名的launchd命令启动.您可以检查守护程序是否在活动监视器应用程序中运行(如果在模拟器中运行),并且其父进程已启动.
我的猜测是,由于任何未知的原因,安全守护程序可能无法启动或执行速度太慢而且在您尝试使用它时尚未就绪.
也许你可以考虑如何预启动守护进程.
我为没有更精确的道歉而道歉.我希望它可以帮助你进一步研究你的调查.
基本上,您必须通过在测试目标中添加以下作为运行脚本来对.xcttest文件夹进行编码.
codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH"
在设备上测试我的钥匙串时,我收到了很多-34018错误,并设法解决了这个问题.
如果您的测试目标中不存在该问题,则可能不是解决方案.
在使用iOS 8 SDK在Xcode 6 beta中构建和运行我的代码后,我观察到类似的行为(它与Xcode 5/iOS 7一起正常工作).在Xcode 6中,在iOS模拟器中,SecItemCopyMatching始终返回-34018.它在"功能"选项卡中打开"钥匙串共享"后开始工作.
但是我有另一个问题.我正在开发静态库,由(以及其他)Demo应用程序使用.上面的解决方案适用于Demo应用程序项目,但是当我尝试单元测试我的静态库项目时,我有完全相同的错误.问题是我的静态库项目没有Capabilities选项卡(因为它不是独立的应用程序).
我已经尝试过JorgeDeCorte在这里发布的解决方案,它在测试目标中进行了编码,但它对我不起作用.