2012-05-10 38 views
69

我目前在iOS KeyChain中存储用户名(电子邮件)和电子邮件和密码的盐渍散列。我正在使用ARC'ified版本号为hereiOS KeyChain不从后台检索值

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil]; 
[wrapper setObject:APP_NAME forKey:(__bridge id)kSecAttrService]; 
[wrapper setObject:email forKey:(__bridge id)kSecAttrAccount]; 
[wrapper setObject:token forKey:(__bridge id)kSecValueData]; 

当我需要在应用程序处于活动状态时为我的网络调用拉出令牌时,这一切都正常。它适用于从干净的启动以及所有网络呼叫登录。当应用程序在后台时,麻烦就开始了。

请记住,这只是偶尔发生,我还没有把它固定到特定的iOS版本或设备。

用户出发一个位置(区域监控),我想用他们的状态更新服务器。我尝试将令牌从钥匙串中取出,就像我为其他网络调用一样,并更新状态。但对于一些用户,价值为零。没有它,我无法更新网络内容。为什么这个工作对大多数人来说,但不是一小部分?

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil]; 
NSString *token = [wrapper objectForKey:(__bridge id)kSecValueData]; 

,我又回到了keychainwrapper的非ARC版本,但我仍然得到同样的结果。我将不胜感激这方面的任何反馈。这只是我用户的一小部分,但这是我想解决的问题,不用担心。提前致谢。

此外,我所有的背景工作都是在backgroundTask中设置的,以防止事情超时。我对围绕钥匙链的工作没有任何问题,但我不会让事情继续下去,直到我的令牌被填满。

编辑 我已经找出了我的问题,他们的keychain没有从背景中检索值。我会在下面发表答案并接受它,因为我觉得这个问题以后可能对其他人有价值。

回答

93

我的问题接近标准为什么,但不是很完美。在博客阅读完博客后,在教程之后的教程中,我终于找到了一个发现可能发生的事情的暗示。

锁定的主屏幕。钥匙串教程始终将钥匙串空白的可访问性设置留下,因此它将默认为Apple最低/最安全的访问级别。但是,如果用户在锁定屏幕上有密码,此级别不允许钥匙串访问。答对了!这解释了零星行为以及为什么这只发生在一小部分用户身上。

一行代码,解决了整个混乱。

[wrapper setObject:(__bridge id)kSecAttrAccessibleAlways forKey:(__bridge id)kSecAttrAccessible]; 

添加此行以设置用户名和密码值。奇迹般有效。希望这会帮助那里的人。它让我困惑了很长一段时间,直到我能够把这些东西拼凑起来。

+1

谢谢!这非常有帮助。 –

+0

很高兴我能帮到你。它让我困惑很长时间。 –

+1

非常感谢你分享这个! – pxlshpr

43

使用kSecAttrAccessibleAfterFirstUnlock而不是kSecAttrAccessibleAlways


Apple's documentation

kSecAttrAccessibleAfterFirstUnlock
The data in the keychain item cannot be accessed after a restart until the device has been unlocked once by the user.

After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute migrate to a new device when using encrypted backups.

+3

这个答案应该是一个评论... – Frizlab

0

在我的情况下,watchOS2访问在iOS端的钥匙串数据。

开始时,使用kSecAttrAccessibleWhenUnlockedThisDeviceOnly。无论iPhone是否锁定,我都可以读取数据。这是非常混乱,我认为我会收到错误时手表试图访问钥匙串: :SecTrustEvaluate [叶IssuerCommonName SubjectCommonName]

而且有些情况下,它会变成: :SecOSStatusWith错误:[ - 25308]误差区域= NSOSStatusErrorDomain代码= -25308“ks_crypt:e00002e2未能'oe'项目(class 6,bag:0)钥匙串被锁定时试图访问项目。 UserInfo = {NSDescription = ks_crypt:e00002e2未能'oe'项目(class 6,bag:0)在钥匙串被锁定时尝试访问项目}

如果我获得更多信息,我会更新我的答案。