iOS's Keychain service provides a safe way to save private information (passwords, serial numbers, certificates, etc.). Each iOS program has a separate keychain store. Starting with iOS 3.0, sharing keychain across programs becomes feasible.
It is convenient to use Apple's official keychainitemwrapper or sfhfkeychainutils.
Apple already has a ready-made class that encapsulates keychain,keychainitemwrapper.h and keychainitemwrapper.m files and can be found in generickeychain instances.
The following is the use of keychain to access user names and passwords.
The code is as follows:
CHKeychain.h
[CPP] view plain copy #import <Foundation/Foundation.h> #import <Security/Security.h> @int Erface Chkeychain:nsobject + (void) Save: (NSString *) service data: (ID) data; + (ID) Load: (NSString *) service; + (void) Delete: (NSString *) service; @end
Chkeychain.m
[CPP] View plain copy #import "CHKeychain.h" @implementation CHKeychain + (nsmutabledictionary *) Getkeychainquery: (nsstring *) service { return [NSMutableDictionary dictionaryWithObjectsAndKeys: (ID) Ksecclassgenericpassword, (ID) ksecclass, service, (ID) ksecattrservice, service, (ID) ksecattraccount, (ID) ksecattraccessibleafterfirstunlock, (ID) ksecattraccessible, nil]; } + (void) Save: (NSString *) Service daTA: (ID) data { //Get search dictionary NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Delete old item before add new item secitemdelete ((cfdictionaryref) keychainquery); //add new object to search dictionary (Attention:the data format) [keychainQuery setObject:[NSKeyedArchiver Archiveddatawithrootobject:data] forkey: (ID) ksecvaluedata]; //add item to keychain with the search dictionary secitemadd ((cfdictionaryref) keychainquery, null); } + (ID) Load: (nsstring *) service { id ret = nil; nsmutabledictionary *keychainQuery = [self getKeychainQuery:service]; // configure the search setting //Since in our Simple case we are expecting only a single attribute to be returned (The password) we can set the attribute ksecreturndata to kCFBooleanTrue [keychainquery setobject: (ID) Kcfbooleantrue forkey: (ID) ksecreturndata]; [keychainQuery SetObject: (ID) Ksecmatchlimitone forkey: (ID) ksecmatchlimit]; cfdataref keyData = NULL; if (secitemcopymatching ( CFDICTIONARYREF) keychainquery, (cftyperef *) (&keydata) == noerr) { @try { ret = [nskeyedunarchiver unarchiveobjectwithdata: (nsdata *) keydata]; } @catch (nsexception *e) { nslog (@ "unarchive of %@ failed: %@", service, e); } @finally { } } if (keyData) cfrelease (keyData); return ret; }