2

I am using the keychain wrapper found here:

https://gist.github.com/1170641

Like this:

.h :

    #import "KeychainItemWrapper.h"

    KeychainItemWrapper *keychainItem;

.m:

 keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"login" accessGroup:nil];

NSString *password = [keychainItem objectForKey:(__bridge id)kSecValueData];
NSString *username = [keychainItem objectForKey:(__bridge id)kSecAttrAccount];

Then it crashes with:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_NSZeroData _fastCharacterContents]: unrecognized selector sent to instance 0x14dcba60'

EDIT:

The crash is no longer present thanks to a user who answered the question but when I retrieve the username or password they are sometimes swaped and I mean 80% of the time.

donkey
  • 1,343
  • 13
  • 32

2 Answers2

3

Edit: I'm using kSecValueData but commented out //#define PASSWORD_USES_DATA in KeychainItemWrapper.m. Also I started using resetKeychainItem instead of trying to override the values myself.

Old Answer: I had this issue until I changed kSecValueData to kSecAttrService, which can be used for passwords also according to SecItem.h. Now everything seems to work fine (setting and retrieving).

Philippe Sabourin
  • 8,066
  • 3
  • 31
  • 46
  • There is no more crash but now when doing this: password = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)]; username = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)]; [usernameTF setText:username]; [passwordTF setText:password]; The password is put in the username field before when using NSUSerDefaults it wouldn't. – donkey Nov 26 '13 at 19:56
  • Error on my part I put both as kSecAttrAccount when the password should be kSecAttrService. – donkey Nov 26 '13 at 20:54
  • I advised you incorrectly. I went back to using kSecValueData but commented out the //#define PASSWORD_USES_DATA near the top KeychainItemWrapper. Also I use resetKeychainItem to delete the password. Will Edit my answer. – Philippe Sabourin Nov 26 '13 at 22:51
  • Ah ok I will change it. Just what is the difference between these keys? – donkey Nov 27 '13 at 04:26
  • I'm not exactly sure. I think they represent different fields of the things you can store within the keychain. The documentation I've read on them is pretty sparse though. – Philippe Sabourin Nov 27 '13 at 14:03
  • Ah could you post a link to the documentation? – donkey Nov 27 '13 at 15:22
  • https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898-CH4g-SW7 – Philippe Sabourin Dec 02 '13 at 18:59
1

I had a similar issue and I fixed it by changing this:

NSString *password = [keychainItem objectForKey:(__bridge id)kSecValueData];
NSString *username = [keychainItem objectForKey:(__bridge id)kSecAttrAccount];

to this:

NSString *password = [[NSString alloc] initWithData:[keychainItem objectForKey:(id)kSecValueData] encoding:NSUTF8StringEncoding];
NSString *username = [keychainItem objectForKey:(id)kSecAttrAccount];
davis
  • 1,137
  • 1
  • 10
  • 28