Sometimes when I run an application on device from Xcode I would try to access the keychain but fail due to error -34018. This doesn't match any of the documented keychain error codes and can't be consistently reproduced. (happens maybe 30% of the time, and it's not clear to me why it happens). What makes debugging this problem very difficult is the total lack of documentation. Any idea what causes this and how to fix it? I'm using Xcode 5 and running iOS 7.0.4 on device.
There is an open issue about this here: https://github.com/soffes/sskeychain/issues/52
EDIT: Adding keychain access code per request
I'm using the SSKeychain
library for interfacing with keychain. Here's the snippet.
#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
Vast majority of the time it's just fine. Sometimes I'll hit the assertion failures where I'm unable to either write to or read from keychain, causing critical assertion failure.
I was having the same problem, out of the blue, running on a test device with Xcode 6.2, iPhone 6, iOS 8.3. To be clear, this was not experienced while running Xcode tests, but rather while running the actual app on my device. In the simulator it was fine, and running on the app itself it had been perfectly fine until recently.
I tried all of the suggestions I could find here, such as removing the provisioning profiles on my device (I removed ALL of them), temporarily enabling the Keychain Sharing capability in my project (even though we don't really need that), making sure my development account in Xcode was totally refreshed with all of the certificates and provisioning profiles, etc. Nothing helped.
Then I temporarily changed the accessibility level from
kSecAttrAccessibleAfterFirstUnlock
tokSecAttrAccessibleAlwaysThisDeviceOnly
, ran the app, and it worked fine and was able to write to the Keychain. Then I changed it back tokSecAttrAccessibleAfterFirstUnlock
, and the problem seems to have gone away "permanently."