Search code examples
iosiphoneobjective-ckeychainkeychainitemwrapper

iOS restore password in login box from keychain


I am saving username/password to keychain like so:

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

[keychainItem setObject:usernameField.text forKey:(__bridge id)(kSecAttrAccount)];
[keychainItem setObject:passwordField.text forKey:(__bridge id)(kSecValueData)];

then I retrieve the username password:

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

then I want to auto put them in the username and password login box if the user checked remember me:

if ([_rememberMeSwitch isOn]) {
    usernameField.text = username;
}

if ([_rememberMeSwitch isOn]) {
    passwordField.text = password;
}

This works fine for username, but password is apparently being saved in the keychain as nscfdata, because when I try to insert password into passwordField.text I get:

[__NSCFData _encodingCantBeStoredInEightBitCFString]: unrecognized selector sent to instance

Is what I am trying to do just considered bad practice or is there an easy way around this?


Solution

  • The docs are clear on it: kSecValueData should be NSData / CFDataRef => so you have to convert your string to data

    to store it

    convert your password text to NSData

    NSData *pwdData = [passwordField.text dataUsingEncoding:NSUTF8StringEncoding];
    

    to read it

    convert the NSData to your password

    NSData *pwdData = [keychainItem objectForKey:(__bridge id)(kSecValueData)];
    NSString *password = [[NSString alloc] initWithData:pwdData encoding:NSUTF8StringEncoding];
    passwordField.text = password;