【发布时间】:2014-03-11 17:47:33
【问题描述】:
我有这个方法可以检查我们是否在钥匙串中存储了用户名和密码:
- (BOOL)hasLoginDetails
{
FLog
NSString *username = [self.keychainItem objectForKey:(__bridge id)kSecAttrAccount];
if (username == nil || [username isEqualToString:@""])
return NO;
NSData *passData = [self.keychainItem objectForKey:(__bridge id)kSecValueData];
if (passData == nil || [passData length] == 0)
return NO;
NSString *password = [[NSString alloc] initWithData:passData encoding:NSUTF8StringEncoding];
if (password == nil || [password isEqualToString:@""])
return NO;
return YES;
}
密码返回为NSData,因此需要转换为字符串。这在正常使用中工作得非常好,但是当它在后台使用application:performFetchWithCompletionHandler: 方法时,我有时会遇到指向这一行的崩溃:
NSString *password = [[NSString alloc] initWithData:passData encoding:NSUTF8StringEncoding];
崩溃日志抱怨
-[__NSCFString bytes]: unrecognized selector sent to instance 0x156104a0
我只在分发 AdHoc 构建后才看到这些崩溃。
我假设崩溃日志说 passData 变量此时实际上是一个字符串?
有什么想法吗?
谢谢
编辑----
密码被添加到钥匙串中,只需使用[self.keychainItem setObject:password forKey:(__bridge id)kSecValueData]; password 作为 NSString。我正在使用来自here 的 KeychainItemWrapper,它将密码 NSString 转换为 NSData 但不会再次将其转换回来,这就是我这样做的原因。
编辑 2 ----
在调试崩溃后,我检查了你的 passData 变量,实际上应该是 NSData 的 NSString,所以有时我得到 NSData,而且我时不时地得到 NSString。
【问题讨论】:
-
你能发布完整的跟踪吗?请大意
-
如何设置
[self.keychainItem objectForKey:(__bridge id)kSecValueData];是在其中放置NSData还是插入NSString? -
kSecValueData的类型是什么?为什么你不能把它留为NSString? -
我相信
KeychainItemWrapper将 NSString 转换为 NSData 以获得更高的安全性。这是为密码字段自动完成的。
标签: ios nsstring nsdata unrecognized-selector keychainitemwrapper