我有这种方法可以检查我们是否在钥匙串中存储了用户名和密码:
- (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即可将密码添加到钥匙串中。我从这里使用 KeychainItemWrapper将密码 NSString 转换为 NSData 但不会再次将其转换回来,这就是我这样做的原因。
编辑 2 ----
在调试崩溃后,我检查了你的 passData 变量,实际上应该是 NSData 的 NSString,所以有时我会得到 NSData,而且我时不时会得到 NSString。