Apple has provided KeyChainItemWrapper class in their GenericKeyChain sample code. There is an ARC'ed solution here on SO, which I am trying to follow: wrapper to store in the KeyChain on iOS.
The usage of the wrapper is like this:
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"F11-email-auth" accessGroup:nil];
[keychain setObject:[emailTextfield text] forKey:(__bridge id)(kSecMatchEmailAddressIfPresent)];
[keychain setObject:[passwordTextfield text] forKey:(__bridge id)(kSecClassGenericPassword)];
the line with email text field is accepted. But the second line with the password crashes with the following exception.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't add the Keychain Item.'
*** First throw call stack:
(
0 CoreFoundation 0x01b445e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x018c78b6 objc_exception_throw + 44
2 CoreFoundation 0x01b44448 +[NSException raise:format:arguments:] + 136
3 Foundation 0x014a823e -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 Feeltracker 0x000053b3 -[KeychainItemWrapper writeToKeychain] + 899
5 Feeltracker 0x00004700 -[KeychainItemWrapper setObject:forKey:] + 272
6 Feeltracker 0x000092d6 -[FTLoginViewController connectToAccount:] + 374
7 libobjc.A.dylib 0x018d9874 -
What could be the reason? I wonder if it has anything to do with the constants I am using.
UPDATE:
Thanks to rmaddy's help:
This is the bit that seems to throw the error:
// No previous item found; add the new one.
result = SecItemAdd((__bridge CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
NSAssert( result == noErr, @"Couldn't add the Keychain Item." );
result is at -50. The SecItemAdd is a lib method. As I was expecting, this is somehow related to the KeyChain handling directly...
keychainItemData contains: