有时,当我在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 …Run Code Online (Sandbox Code Playgroud) 更新:此问题已在Xcode 8.2中修复.Keychain在模拟器中工作,无需启用钥匙串共享.
为什么在Xcode 8/iOS 10模拟器中调用函数时总是收到错误-34018 ?SecItemAdd
在Xcode 8中创建一个新的单页iOS应用程序项目.运行以下代码viewDidLoad(或打开此 Xcode项目).
let itemKey = "My key"
let itemValue = "My secretive bee "
// Remove from Keychain
// ----------------
let queryDelete: [String: AnyObject] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: itemKey as AnyObject
]
let resultCodeDelete = SecItemDelete(queryDelete as CFDictionary)
if resultCodeDelete != noErr {
print("Error deleting from Keychain: \(resultCodeDelete)")
}
// Add to keychain
// ----------------
guard let valueData …Run Code Online (Sandbox Code Playgroud) 我SecItemCopyMatching用来访问iOS钥匙串.大约一百次,我-34018在从后台重新启动应用程序后立即获得结果代码.文件说明:
Keychain Services的指定错误空间是不连续的:-25240到-25279和-25290到-25329.Keychain Item Services也可以返回noErr(0)或paramErr(-50)或CSSM结果代码
所以它似乎-34018是一个'CSSM结果代码'.我已按照建议的链接但找不到结果代码.
它的-34018结果代码?如何获得更可靠的钥匙串访问?
- (NSData *)getKeychainData:(NSString *)key
{
NSDictionary *query = @{
(__bridge id)kSecClass:(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService:SEC_ATTR_SERVICE,
(__bridge id)kSecAttrAccount:key,
(__bridge id)kSecReturnData:@YES
};
CFDataRef result = nil;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
if(status == errSecItemNotFound) {
return nil;
}
if(status == noErr) {
return CFBridgingRelease(result);
} else {
[self logError:[NSString stringWithFormat:@"SecItemCopyMatching status %d", (int)status] :nil];
return nil;
}
}
Run Code Online (Sandbox Code Playgroud)