[ios] iOS: How to store username/password within an app?

I have a login-screen in my iOS app. The username and password will be saved in the NSUserDefaults and be loaded into the login-screen again when you enter the app again (of course, NSUserDefaults are permanent).

Now, the user have the possibility to disable the username/password saving feature.

So the NSUserDefaults will be cleared then.

But In my app I need this username/password for database queries for the user. So: Where to store the data except NSUserDefaults? (This place can / should be deleted when the user quit the app or logout).

This question is related to ios nsuserdefaults keychain

The answer is


The following should work just fine:

KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[keychainItem setObject:@"password you are saving" forKey:kSecValueData]; 
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];

I looked at using KeychainItemWrapper (the ARC version) but I didn't find its Objective C wrapper as wholesome as desired.

I used this solution by Kishikawa Katsumi, which meant I wrote less code and didn't have to use casts to store NSString values.

Two examples of storing:

[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username"];
[UICKeyChainStore setString:@"P455_w0rd$1$G$Z$" forKey:@"password"];

Two examples of retrieving

UICKeyChainStore *store = [UICKeyChainStore keyChainStore];
    // or
UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:@"YOUR_SERVICE"];

NSString *username = [store stringForKey:@"username"];
NSString *password = [store stringForKey:@"password"];

A very easy solution via Keychains.

It's a simple wrapper for the system Keychain. Just add the SSKeychain.h, SSKeychain.m, SSKeychainQuery.h and SSKeychainQuery.m files to your project and add the Security.framework to your target.

To save a password:

[SSKeychain setPassword:@"AnyPassword" forService:@"AnyService" account:@"AnyUser"]

To retrieve a password:

NSString *password = [SSKeychain passwordForService:@"AnyService" account:@"AnyUser"];

Where setPassword is what value you want saved and forService is what variable you want it saved under and account is for what user/object the password and any other info is for.


I decided to answer how to use keychain in iOS 8 using Obj-C and ARC.

1)I used the keychainItemWrapper (ARCifief version) from GIST: https://gist.github.com/dhoerl/1170641/download - Add (+copy) the KeychainItemWrapper.h and .m to your project

2) Add the Security framework to your project (check in project > Build phases > Link binary with Libraries)

3) Add the security library (#import ) and KeychainItemWrapper (#import "KeychainItemWrapper.h") to the .h and .m file where you want to use keychain.

4) To save data to keychain:

NSString *emailAddress = self.txtEmail.text;
NSString *password = self.txtPasword.text;
//because keychain saves password as NSData object
NSData *pwdData = [password dataUsingEncoding:NSUTF8StringEncoding];

//Save item
self.keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[self.keychainItem setObject:emailAddress forKey:(__bridge id)(kSecAttrAccount)];
[self.keychainItem setObject:pwdData forKey:(__bridge id)(kSecValueData)];

5) Read data (probably login screen on loading > viewDidLoad):

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

self.txtEmail.text = [self.keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];

//because label uses NSString and password is NSData object, conversion necessary
NSData *pwdData = [self.keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSString *password = [[NSString alloc] initWithData:pwdData encoding:NSUTF8StringEncoding];
self.txtPassword.text = password;

Enjoy!


For swift you can use this library:

https://github.com/jrendel/SwiftKeychainWrapper

It supports all versions of swift.


To update this question:

For those using Swift checkout this drag and drop swift implementation by Mihai Costea supporting access groups:

https://github.com/macostea/KeychainItemWrapper.swift/blob/master/KeychainItemWrapper.swift

Before using the keychain: consider twice before storing passwords. In many cases storing an authentication token (such as a persistence session id) and the email or account name might be enough. You can easily invalidate authentication tokens to block unauthorized access, requiring the user to login again on the compromised device but not requiring reset password and having to login again on all devices (we are not only using Apple are we?).


But, now you can go for NURLCredential instead of keychain wrapper. It does what we need to do.


try this one:

 KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[keychainItem setObject:@"password you are saving" forKey:kSecValueData]; 
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];

may it will help.


If you are having an issue retrieving the password using the keychain wrapper, use this code:

NSData *pass =[keychain objectForKey:(__bridge id)(kSecValueData)];
NSString *passworddecoded = [[NSString alloc] initWithData:pass
                                           encoding:NSUTF8StringEncoding];

checkout this sample code i tried first the apple's wrapper from the sample code but this is much simpler for me


There is a small bug in the above code (by the way Dave it was very helpful your post thank you)

In the part where we save the credentials it also needs the following code in order to work properly.

[self.keychainItem setObject:@"myCredentials" forKey:(__bridge id)(kSecAttrService)];

most probably is because the second time we try to (re-)sign in with the same credentials it finds them already assigned in the keychain items and the app crashes. with the above code it works like a charm.


You can simply use NSURLCredential, it will save both username and password in the keychain in just two lines of code.

See my detailed answer.


If you need an ARC version of the wrapper here is the link https://gist.github.com/1170641 Thanks to


Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to nsuserdefaults

How can I use UserDefaults in Swift? How to save local data in a Swift app? how to save and read array of array in NSUserdefaults in swift? Attempt to set a non-property-list object as an NSUserDefaults iOS: How to store username/password within an app? Save string to the NSUserDefaults? How to store custom objects in NSUserDefaults NSUserDefaults - How to tell if a key exists Clearing NSUserDefaults

Examples related to keychain

Distribution certificate / private key not installed Codesign wants to access key "access" in your keychain, I put in my login password but keeps asking me This certificate has an invalid issuer Apple Push Services How can I add private key to the distribution certificate? missing private key in the distribution certificate on keychain How to obtain Certificate Signing Request iOS: How to store username/password within an app? Xcode 4 - "Valid signing identity not found" error on provisioning profiles on a new Macintosh install Delete keychain items when an app is uninstalled How to convert SSH keypairs generated using PuTTYgen (Windows) into key-pairs used by ssh-agent and Keychain (Linux)