I am facing a weird issue. Quite similar to one asked here, but not answered: Read from keychain results in errSecItemNotFound 25300
My code saves a string password in the iOS keychain to be accessed later on. It works just fine most of the times and I am able to fetch the password back after reinstallation or device restart or both.
Problem: Sometimes which is actually rare and hard to reproduce, it does not return the password and instead it returns null and error status:-25300(errSecItemNotFound). Another thing is that this problem got prominent after iOS 9 update. Happening on iOS 9.1 too.
Now, I have been searching the web for a solution. Found the following, which somehow relate to the issue, but do not address to my scenario:
- iOS Keychain Data Lost Upon iPhone Memory Pressure?
- https://forums.developer.apple.com/thread/4743
- iOS KeyChain not retrieving values from background
Has anyone got any ideas why this is happening? Many thanks.
Updated
Code for setting:
NSMutableDictionary *query = [self _queryForService:service account:account];
[query setObject:password forKey:(__bridge id)kSecValueData];
status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
}
if (status != errSecSuccess && error != NULL) {
*error = [NSError errorWithDomain:kAppKeychainErrorDomain code:status userInfo:nil];
}
return (status == noErr);
Final query:
{
acct = user;
class = genp;
svce = "myBundleIdentifier";
"v_Data" = <36314541 38463339 2d363737 462d3445 34372d42 4339452d 31324633 46463937 35374546>;}
Code for fetching:
CFTypeRef result = NULL;
NSMutableDictionary *query = [self _queryForService:service account:account];
[query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
[query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
if (status != errSecSuccess && error != NULL) {
*error = [NSError errorWithDomain:kAppKeychainErrorDomain code:status userInfo:nil];
return nil;
}
return (__bridge_transfer NSData *)result;
Final query:
{
acct = user;
class = genp;
"m_Limit" = "m_LimitOne";
"r_Data" = 1;
svce = "myBundleIdentifier";}