首页 > 代码库 > iOS 使用Keychain 保存 用户名和密码到 本地
iOS 使用Keychain 保存 用户名和密码到 本地
iOS 使用Keychain 保存 用户名和密码到 本地
之前曾把一些简单的数据保存在了plist,文件,及NsuserDefault里面,
但是如果要保存密码之类的,保存在本地就很不安全了;
但是利用 Keychain 我们可以很安全的把 用户密码等信息保存在本地
1:使用苹果官方封装好的Keychain操作类
GenericKeychain
2:使用 开源的keychain操作
sskeychain
#import <XCTest/XCTest.h>#import "SSKeychain.h"static NSString *const kSSKeychainServiceName = @"SSToolkitTestService";static NSString *const kSSKeychainAccountName = @"SSToolkitTestAccount";static NSString *const kSSKeychainPassword = @"SSToolkitTestPassword";static NSString *const kSSKeychainLabel = @"SSToolkitLabel";@interface SSKeychainTests : XCTestCase@end@implementation SSKeychainTests- (void)testNewItem { // New item SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; query.password = kSSKeychainPassword; query.service = kSSKeychainServiceName; query.account = kSSKeychainAccountName; query.label = kSSKeychainLabel; NSError *error; XCTAssertTrue([query save:&error], @"Unable to save item: %@", error); // Look up query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; query.account = kSSKeychainAccountName; query.password = nil; XCTAssertTrue([query fetch:&error], @"Unable to fetch keychain item: %@", error); XCTAssertEqualObjects(query.password, kSSKeychainPassword, @"Passwords were not equal"); // Search for all accounts query = [[SSKeychainQuery alloc] init]; NSArray *accounts = [query fetchAll:&error]; XCTAssertNotNil(accounts, @"Unable to fetch accounts: %@", error); XCTAssertTrue([self _accounts:accounts containsAccountWithName:kSSKeychainAccountName], @"Matching account was not returned"); // Check accounts for service query.service = kSSKeychainServiceName; accounts = [query fetchAll:&error]; XCTAssertNotNil(accounts, @"Unable to fetch accounts: %@", error); XCTAssertTrue([self _accounts:accounts containsAccountWithName:kSSKeychainAccountName], @"Matching account was not returned"); // Delete query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; query.account = kSSKeychainAccountName; XCTAssertTrue([query deleteItem:&error], @"Unable to delete password: %@", error);}- (void)testPasswordObject { SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; query.account = kSSKeychainAccountName; NSDictionary *dictionary = @{@"number": @42, @"string": @"Hello World"}; query.passwordObject = dictionary; NSError *error; XCTAssertTrue([query save:&error], @"Unable to save item: %@", error); query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; query.account = kSSKeychainAccountName; query.passwordObject = nil; XCTAssertTrue([query fetch:&error], @"Unable to fetch keychain item: %@", error); XCTAssertEqualObjects(query.passwordObject, dictionary, @"Passwords were not equal");}- (void)testMissingInformation { SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; query.account = kSSKeychainAccountName; NSError *error; XCTAssertFalse([query save:&error], @"Function should return NO as not all needed information is provided: %@", error); query = [[SSKeychainQuery alloc] init]; query.password = kSSKeychainPassword; query.account = kSSKeychainAccountName; XCTAssertFalse([query save:&error], @"Function should return NO as not all needed information is provided: %@", error); query = [[SSKeychainQuery alloc] init]; query.password = kSSKeychainPassword; query.service = kSSKeychainServiceName; XCTAssertFalse([query save:&error], @"Function save should return NO if not all needed information is provided: %@", error);}- (void)testDeleteWithMissingInformation { SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; query.account = kSSKeychainAccountName; NSError *error; XCTAssertFalse([query deleteItem:&error], @"Function deleteItem should return NO if not all needed information is provided: %@", error); query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; XCTAssertFalse([query deleteItem:&error], @"Function deleteItem should return NO if not all needed information is provided: %@", error); // check if fetch handels missing information correctly query = [[SSKeychainQuery alloc] init]; query.account = kSSKeychainAccountName; XCTAssertFalse([query fetch:&error], @"Function fetch should return NO if not all needed information is provided: %@", error); query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; XCTAssertFalse([query fetch:&error], @"Function fetch should return NO if not all needed information is provided: %@", error); query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; XCTAssertFalse([query fetch:NULL], @"Function fetch should return NO if not all needed information is provided and error is NULL");}- (void)testSynchronizable { SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; query.account = kSSKeychainAccountName; query.password = kSSKeychainPassword; query.synchronizationMode = SSKeychainQuerySynchronizationModeYes; NSError *error; XCTAssertTrue([query save:&error], @"Unable to save item: %@", error); query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; query.account = kSSKeychainAccountName; query.password = nil; query.synchronizationMode = SSKeychainQuerySynchronizationModeNo; XCTAssertFalse([query fetch:&error], @"Fetch should fail when trying to fetch an unsynced password that was saved as synced: %@", error); XCTAssertFalse([query fetch:NULL], @"Fetch should fail when trying to fetch an unsynced password that was saved as synced. error == NULL"); XCTAssertNotEqualObjects(query.password, kSSKeychainPassword, @"Passwords should not be equal when trying to fetch an unsynced password that was saved as synced."); query = [[SSKeychainQuery alloc] init]; query.service = kSSKeychainServiceName; query.account = kSSKeychainAccountName; query.password = nil; query.synchronizationMode = SSKeychainQuerySynchronizationModeAny; XCTAssertTrue([query fetch:&error], @"Unable to fetch keychain item: %@", error); XCTAssertEqualObjects(query.password, kSSKeychainPassword, @"Passwords were not equal");}// Test Class Methods of SSKeychain- (void)testSSKeychain { NSError *error = nil; // create a new keychain item XCTAssertTrue([SSKeychain setPassword:kSSKeychainPassword forService:kSSKeychainServiceName account:kSSKeychainAccountName error:&error], @"Unable to save item: %@", error); // check password XCTAssertEqualObjects([SSKeychain passwordForService:kSSKeychainServiceName account:kSSKeychainAccountName], kSSKeychainPassword, @"Passwords were not equal"); // check all accounts XCTAssertTrue([self _accounts:[SSKeychain allAccounts] containsAccountWithName:kSSKeychainAccountName], @"Matching account was not returned"); // check account XCTAssertTrue([self _accounts:[SSKeychain accountsForService:kSSKeychainServiceName] containsAccountWithName:kSSKeychainAccountName], @"Matching account was not returned"); // delete password XCTAssertTrue([SSKeychain deletePasswordForService:kSSKeychainServiceName account:kSSKeychainAccountName error:&error], @"Unable to delete password: %@", error); // set password and delete it without error function XCTAssertTrue([SSKeychain setPassword:kSSKeychainPassword forService:kSSKeychainServiceName account:kSSKeychainAccountName], @"Unable to save item"); XCTAssertTrue([SSKeychain deletePasswordForService:kSSKeychainServiceName account:kSSKeychainAccountName], @"Unable to delete password"); #if __IPHONE_4_0 && TARGET_OS_IPHONE [SSKeychain setAccessibilityType:kSecAttrAccessibleWhenUnlockedThisDeviceOnly]; XCTAssertTrue([SSKeychain accessibilityType] == kSecAttrAccessibleWhenUnlockedThisDeviceOnly, @"Unable to verify accessibilityType");#endif}#pragma mark - Private- (BOOL)_accounts:(NSArray *)accounts containsAccountWithName:(NSString *)name { for (NSDictionary *dictionary in accounts) { if ([[dictionary objectForKey:@"acct"] isEqualToString:name]) { return YES; } } return NO;}@end
UICKeyChainStore
#import <XCTest/XCTest.h>#import "UICKeyChainStore.h"@interface UICKeyChainStoreTests : XCTestCase { NSString *kStubKey; NSString *kStubString; NSString *kStubService;}@end@implementation UICKeyChainStoreTests- (void)setUp{ [super setUp]; kStubKey = @"password"; kStubString = @"password1234"; kStubService = @"com.kishikawakatsumi"; [UICKeyChainStore setDefaultService:kStubService]; [UICKeyChainStore removeAllItems];}- (void)tearDown{ [super tearDown];}- (void)testSetDefaultService{ NSString *serviceName = @"com.kishikawakatsumi.UICKeyChainStore"; [UICKeyChainStore setDefaultService:serviceName]; XCTAssertEqualObjects(serviceName, [UICKeyChainStore defaultService], @"specitfy default service name");}- (void)testInitializers{ UICKeyChainStore *store = nil; store = [UICKeyChainStore keyChainStore]; XCTAssertEqualObjects(store.service, [UICKeyChainStore defaultService], @"instantiate default store"); store = [[UICKeyChainStore alloc] init]; XCTAssertEqualObjects(store.service, [UICKeyChainStore defaultService], @"instantiate default store"); NSString *serviceName = @"com.kishikawakatsumi.UICKeyChainStore"; store = [UICKeyChainStore keyChainStoreWithService:serviceName]; XCTAssertEqualObjects(store.service, serviceName, @"instantiate custom service named store");}- (void)testSetData{ NSString *usernameKey = @"username"; NSString *passwordKey = @"password"; NSString *username = @"kishikawakatsumi"; NSString *password = @"password1234"; NSData *usernameData =http://www.mamicode.com/ [username dataUsingEncoding:NSUTF8StringEncoding]; NSData *passwordData =http://www.mamicode.com/ [password dataUsingEncoding:NSUTF8StringEncoding]; [UICKeyChainStore setData:[username dataUsingEncoding:NSUTF8StringEncoding] forKey:usernameKey]; [UICKeyChainStore setData:[password dataUsingEncoding:NSUTF8StringEncoding] forKey:passwordKey]; XCTAssertEqualObjects([UICKeyChainStore dataForKey:usernameKey], usernameData, @"stored username"); XCTAssertEqualObjects([UICKeyChainStore dataForKey:passwordKey], passwordData, @"stored password"); [UICKeyChainStore removeItemForKey:usernameKey service:[UICKeyChainStore defaultService]]; XCTAssertNil([UICKeyChainStore dataForKey:usernameKey], @"removed username"); XCTAssertEqualObjects([UICKeyChainStore dataForKey:passwordKey], passwordData, @"left password"); [UICKeyChainStore removeItemForKey:passwordKey service:[UICKeyChainStore defaultService]]; XCTAssertNil([UICKeyChainStore dataForKey:usernameKey], @"removed username"); XCTAssertNil([UICKeyChainStore dataForKey:passwordKey], @"removed password");}- (void)testSetDataWithNoError{ NSString *usernameKey = @"username"; NSString *passwordKey = @"password"; NSString *username = @"kishikawakatsumi"; NSString *password = @"password1234"; NSData *usernameData =http://www.mamicode.com/ [username dataUsingEncoding:NSUTF8StringEncoding]; NSData *passwordData =http://www.mamicode.com/ [password dataUsingEncoding:NSUTF8StringEncoding]; NSError *error; [UICKeyChainStore setData:[username dataUsingEncoding:NSUTF8StringEncoding] forKey:usernameKey error:&error]; XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([UICKeyChainStore dataForKey:usernameKey error:&error], usernameData, @"stored username"); XCTAssertNil(error, @"no error"); [UICKeyChainStore setData:[password dataUsingEncoding:NSUTF8StringEncoding] forKey:passwordKey error:&error]; XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([UICKeyChainStore dataForKey:passwordKey error:&error], passwordData, @"stored password"); XCTAssertNil(error, @"no error"); [UICKeyChainStore removeItemForKey:usernameKey service:[UICKeyChainStore defaultService] error:&error]; XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore dataForKey:usernameKey error:&error], @"removed username"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([UICKeyChainStore dataForKey:passwordKey error:&error], passwordData, @"left password"); XCTAssertNil(error, @"no error"); [UICKeyChainStore removeItemForKey:passwordKey service:[UICKeyChainStore defaultService] error:&error]; XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore dataForKey:usernameKey error:&error], @"removed username"); XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore dataForKey:passwordKey error:&error], @"removed password"); XCTAssertNil(error, @"no error");}- (void)testSetNilData{ NSString *usernameKey = @"username"; NSString *passwordKey = @"password"; NSString *username = @"kishikawakatsumi"; NSString *password = @"password1234"; NSData *usernameData =http://www.mamicode.com/ [username dataUsingEncoding:NSUTF8StringEncoding]; NSData *passwordData =http://www.mamicode.com/ [password dataUsingEncoding:NSUTF8StringEncoding]; [UICKeyChainStore setData:nil forKey:usernameKey]; [UICKeyChainStore setData:nil forKey:passwordKey]; XCTAssertNil([UICKeyChainStore dataForKey:usernameKey], @"no username"); XCTAssertNil([UICKeyChainStore dataForKey:passwordKey], @"no password"); [UICKeyChainStore setData:[username dataUsingEncoding:NSUTF8StringEncoding] forKey:usernameKey]; [UICKeyChainStore setData:[password dataUsingEncoding:NSUTF8StringEncoding] forKey:passwordKey]; XCTAssertEqualObjects([UICKeyChainStore dataForKey:usernameKey], usernameData, @"stored username"); XCTAssertEqualObjects([UICKeyChainStore dataForKey:passwordKey], passwordData, @"stored password"); [UICKeyChainStore setData:nil forKey:usernameKey]; XCTAssertNil([UICKeyChainStore dataForKey:usernameKey], @"removed username"); XCTAssertEqualObjects([UICKeyChainStore dataForKey:passwordKey], passwordData, @"left password"); [UICKeyChainStore setData:nil forKey:passwordKey]; XCTAssertNil([UICKeyChainStore dataForKey:usernameKey], @"removed username"); XCTAssertNil([UICKeyChainStore dataForKey:passwordKey], @"removed password"); [UICKeyChainStore removeItemForKey:usernameKey]; XCTAssertNil([UICKeyChainStore dataForKey:usernameKey], @"removed username"); XCTAssertNil([UICKeyChainStore dataForKey:passwordKey], @"removed password"); [UICKeyChainStore removeItemForKey:passwordKey]; XCTAssertNil([UICKeyChainStore dataForKey:usernameKey], @"removed username"); XCTAssertNil([UICKeyChainStore dataForKey:passwordKey], @"removed password");}- (void)testSetUsernameAndPassword{ NSString *usernameKey = @"username"; NSString *passwordKey = @"password"; NSString *username = @"kishikawakatsumi"; NSString *password = @"password1234"; UICKeyChainStore *store = [UICKeyChainStore keyChainStore]; [store removeAllItems]; [UICKeyChainStore setString:username forKey:usernameKey]; [UICKeyChainStore setString:password forKey:passwordKey]; XCTAssertEqualObjects([UICKeyChainStore stringForKey:usernameKey], username, @"stored username"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey], password, @"stored password"); XCTAssertEqualObjects([store stringForKey:usernameKey], username, @"stored username"); XCTAssertEqualObjects([store stringForKey:passwordKey], password, @"stored password"); [UICKeyChainStore removeItemForKey:usernameKey]; XCTAssertNil([UICKeyChainStore stringForKey:usernameKey], @"removed username"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey], password, @"left password"); XCTAssertEqualObjects([store stringForKey:passwordKey], password, @"left password"); [UICKeyChainStore removeItemForKey:passwordKey]; XCTAssertNil([UICKeyChainStore stringForKey:usernameKey], @"removed username"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey], @"removed password"); XCTAssertNil([store stringForKey:usernameKey], @"removed username"); XCTAssertNil([store stringForKey:passwordKey], @"removed password");}- (void)testSetUsernameAndPasswordWithNoError{ NSString *usernameKey = @"username"; NSString *passwordKey = @"password"; NSString *username = @"kishikawakatsumi"; NSString *password = @"password1234"; NSError *error; UICKeyChainStore *store = [UICKeyChainStore keyChainStore]; [store removeAllItemsWithError:&error]; XCTAssertNil(error, @"no error"); [UICKeyChainStore setString:username forKey:usernameKey error:&error]; XCTAssertNil(error, @"no error"); [UICKeyChainStore setString:password forKey:passwordKey error:&error]; XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:usernameKey error:&error], username, @"stored username"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey error:&error], password, @"stored password"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([store stringForKey:usernameKey error:&error], username, @"stored username"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([store stringForKey:passwordKey error:&error], password, @"stored password"); XCTAssertNil(error, @"no error"); [UICKeyChainStore removeItemForKey:usernameKey error:&error]; XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore stringForKey:usernameKey error:&error], @"removed username"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey error:&error], password, @"left password"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([store stringForKey:passwordKey error:&error], password, @"left password"); XCTAssertNil(error, @"no error"); [UICKeyChainStore removeItemForKey:passwordKey error:&error]; XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore stringForKey:usernameKey error:&error], @"removed username"); XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey error:&error], @"removed password"); XCTAssertNil(error, @"no error"); XCTAssertNil([store stringForKey:usernameKey error:&error], @"removed username"); XCTAssertNil(error, @"no error"); XCTAssertNil([store stringForKey:passwordKey error:&error], @"removed password"); XCTAssertNil(error, @"no error");}- (void)testSetNilUsernameAndNilPassword{ NSString *usernameKey = @"username"; NSString *passwordKey = @"password"; NSString *username = @"kishikawakatsumi"; NSString *password = @"password1234"; UICKeyChainStore *store = [UICKeyChainStore keyChainStore]; [store removeAllItems]; [UICKeyChainStore setString:nil forKey:usernameKey]; [UICKeyChainStore setString:nil forKey:passwordKey]; XCTAssertNil([UICKeyChainStore dataForKey:usernameKey], @"no username"); XCTAssertNil([UICKeyChainStore dataForKey:passwordKey], @"no password"); [UICKeyChainStore setString:username forKey:usernameKey]; [UICKeyChainStore setString:password forKey:passwordKey]; XCTAssertEqualObjects([UICKeyChainStore stringForKey:usernameKey], username, @"stored username"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey], password, @"stored password"); XCTAssertEqualObjects([store stringForKey:usernameKey], username, @"stored username"); XCTAssertEqualObjects([store stringForKey:passwordKey], password, @"stored password"); [UICKeyChainStore setString:nil forKey:usernameKey]; XCTAssertNil([UICKeyChainStore stringForKey:usernameKey], @"removed username"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey], password, @"left password"); XCTAssertEqualObjects([store stringForKey:passwordKey], password, @"left password"); [UICKeyChainStore setString:nil forKey:passwordKey]; XCTAssertNil([UICKeyChainStore stringForKey:usernameKey], @"removed username"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey], @"removed password"); XCTAssertNil([store stringForKey:usernameKey], @"removed username"); XCTAssertNil([store stringForKey:passwordKey], @"removed password");}- (void)testSynchronize1{ NSString *usernameKey = @"username"; NSString *passwordKey = @"password"; NSString *username = @"kishikawakatsumi"; NSString *password = @"password1234"; NSString *serviceName = @"com.example.UICKeyChainStore"; [UICKeyChainStore removeAllItemsForService:serviceName]; UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:serviceName]; [store removeAllItems]; [store setString:username forKey:usernameKey]; [store setString:password forKey:passwordKey]; XCTAssertEqualObjects([store stringForKey:usernameKey], username, @"stored username"); XCTAssertEqualObjects([store stringForKey:passwordKey], password, @"stored password"); XCTAssertNil([UICKeyChainStore stringForKey:usernameKey service:serviceName], @"not synchronized yet"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey service:serviceName], @"not synchronized yet"); [store synchronize]; XCTAssertEqualObjects([store stringForKey:usernameKey], username, @"stored username"); XCTAssertEqualObjects([store stringForKey:passwordKey], password, @"stored password"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:usernameKey service:serviceName], username, @"stored username"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey service:serviceName], password, @"stored password"); [store removeItemForKey:usernameKey]; XCTAssertNil([store stringForKey:usernameKey], @"removed username"); XCTAssertEqualObjects([store stringForKey:passwordKey], password, @"left password"); XCTAssertNil([UICKeyChainStore stringForKey:usernameKey service:serviceName], @"removed username"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey service:serviceName], password, @"left password"); [store removeItemForKey:passwordKey]; XCTAssertNil([store stringForKey:passwordKey], @"removed password"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey service:serviceName], @"removed password");}- (void)testSynchronize2{ NSString *usernameKey = @"username"; NSString *passwordKey = @"password"; NSString *username = @"kishikawakatsumi"; NSString *password = @"password1234"; NSString *serviceName = @"com.example.UICKeyChainStore"; [UICKeyChainStore removeAllItemsForService:serviceName]; UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:serviceName]; [store removeAllItems]; [store setString:username forKey:usernameKey]; [store setString:password forKey:passwordKey]; XCTAssertEqualObjects([store stringForKey:usernameKey], username, @"stored username"); XCTAssertEqualObjects([store stringForKey:passwordKey], password, @"stored password"); XCTAssertNil([UICKeyChainStore stringForKey:usernameKey service:serviceName], @"not synchronized yet"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey service:serviceName], @"not synchronized yet"); [store removeItemForKey:usernameKey]; XCTAssertNil([store stringForKey:usernameKey], @"removed username"); XCTAssertEqualObjects([store stringForKey:passwordKey], password, @"left password"); XCTAssertNil([UICKeyChainStore stringForKey:usernameKey service:serviceName], @"not synchronized yet"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey service:serviceName], @"not synchronized yet"); [store removeItemForKey:passwordKey]; XCTAssertNil([store stringForKey:passwordKey], @"removed password"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey service:serviceName], @"not synchronized yet"); [store synchronize]; XCTAssertNil([store stringForKey:usernameKey], @"removed username"); XCTAssertNil([store stringForKey:passwordKey], @"removed password"); XCTAssertNil([UICKeyChainStore stringForKey:usernameKey service:serviceName], @"removed username"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey service:serviceName], @"removed password");}- (void)testSynchronizeWithNoError{ NSString *usernameKey = @"username"; NSString *passwordKey = @"password"; NSString *username = @"kishikawakatsumi"; NSString *password = @"password1234"; NSString *serviceName = @"com.example.UICKeyChainStore"; NSError *error; [UICKeyChainStore removeAllItemsForService:serviceName error:&error]; XCTAssertNil(error, @"no error"); UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:serviceName]; [store removeAllItemsWithError:&error]; XCTAssertNil(error, @"no error"); [store setString:username forKey:usernameKey error:&error]; XCTAssertNil(error, @"no error"); [store setString:password forKey:passwordKey error:&error]; XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([store stringForKey:usernameKey error:&error], username, @"stored username"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([store stringForKey:passwordKey error:&error], password, @"stored password"); XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore stringForKey:usernameKey service:serviceName error:&error], @"not synchronized yet"); XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey service:serviceName error:&error], @"not synchronized yet"); XCTAssertNil(error, @"no error"); [store synchronizeWithError:&error]; XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([store stringForKey:usernameKey error:&error], username, @"stored username"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([store stringForKey:passwordKey error:&error], password, @"stored password"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:usernameKey service:serviceName error:&error], username, @"stored username"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey service:serviceName error:&error], password, @"stored password"); XCTAssertNil(error, @"no error"); [store removeItemForKey:usernameKey error:&error]; XCTAssertNil(error, @"no error"); XCTAssertNil([store stringForKey:usernameKey error:&error], @"removed username"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([store stringForKey:passwordKey error:&error], password, @"left password"); XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore stringForKey:usernameKey service:serviceName error:&error], @"removed username"); XCTAssertNil(error, @"no error"); XCTAssertEqualObjects([UICKeyChainStore stringForKey:passwordKey service:serviceName error:&error], password, @"left password"); XCTAssertNil(error, @"no error"); [store removeItemForKey:passwordKey error:&error]; XCTAssertNil(error, @"no error"); XCTAssertNil([store stringForKey:passwordKey error:&error], @"removed password"); XCTAssertNil(error, @"no error"); XCTAssertNil([UICKeyChainStore stringForKey:passwordKey service:serviceName error:&error], @"removed password"); XCTAssertNil(error, @"no error");}- (void)testClassMethodsSetAndRemoveItem{ // write to keychain [UICKeyChainStore setString:kStubString forKey:kStubKey]; // read from keychain, test keychain contains item NSString *actualString = [UICKeyChainStore stringForKey:kStubKey]; NSString *expectedString = kStubString; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString); // remove item from keychain [UICKeyChainStore removeItemForKey:kStubKey]; // read from keychain, test keychain doesn‘t contain item actualString = [UICKeyChainStore stringForKey:kStubKey]; expectedString = NULL; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString);}- (void)testClassMethodsSetAndRemoveItemWithNoError{ NSError *error; [UICKeyChainStore setString:kStubString forKey:kStubKey error:&error]; XCTAssertNil(error, @"no error"); NSString *actualString = [UICKeyChainStore stringForKey:kStubKey error:&error]; XCTAssertNil(error, @"no error"); NSString *expectedString = kStubString; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString); // remove item from keychain [UICKeyChainStore removeItemForKey:kStubKey error:&error]; XCTAssertNil(error, @"no error"); // read from keychain, test keychain doesn‘t contain item actualString = [UICKeyChainStore stringForKey:kStubKey error:&error]; XCTAssertNil(error, @"no error"); expectedString = NULL; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString);}- (void)testInstanceMethodsSetAndRemoveItem{ // create an instance UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:kStubService]; // write to keychain [store setString:kStubString forKey:kStubKey]; [store synchronize]; // read from keychain, test keychain contains item NSString *actualString = [store stringForKey:kStubKey]; NSString *expectedString = kStubString; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString); // remove item from keychain [store removeItemForKey:kStubKey]; [store synchronize]; // read from keychain, test keychain doesn‘t contain item actualString = [store stringForKey:kStubKey]; expectedString = NULL; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString); actualString = [store description]; expectedString = @"(\n)"; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString);}- (void)testInstanceMethodsSetAndRemoveItemWithNoError{ NSError *error; UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:kStubService]; [store setString:kStubString forKey:kStubKey error:&error]; XCTAssertNil(error, @"no error"); [store synchronizeWithError:&error]; XCTAssertNil(error, @"no error"); NSString *actualString = [store stringForKey:kStubKey error:&error]; XCTAssertNil(error, @"no error"); NSString *expectedString = kStubString; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString); [store removeItemForKey:kStubKey error:&error]; XCTAssertNil(error, @"no error"); [store synchronizeWithError:&error]; XCTAssertNil(error, @"no error"); actualString = [store stringForKey:kStubKey error:&error]; XCTAssertNil(error, @"no error"); expectedString = NULL; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString); actualString = [store description]; expectedString = @"(\n)"; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString);}- (void)testInstanceMethodsSetAndRemoveWithNilValue{ UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:kStubService]; [store setString:kStubString forKey:kStubKey]; [store synchronize]; NSString *actualString = [store stringForKey:kStubKey]; NSString *expectedString = kStubString; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString); [store setString:nil forKey:kStubKey]; [store synchronize]; actualString = [store stringForKey:kStubKey]; expectedString = NULL; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString); actualString = [store description]; expectedString = @"(\n)"; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString);}- (void)testObjectSubscripting{ // create an instance UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:kStubService]; // write to keychain using obj subscripting store[kStubKey] = kStubString; [store synchronize]; NSString *actualString = store[kStubKey]; NSString *expectedString = kStubString; // read from keychain using obj subscripting XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString); store[kStubKey] = nil; [store synchronize]; actualString = store[kStubKey]; expectedString = NULL; XCTAssertEqualObjects(expectedString, actualString, @"expected %@ but got %@", expectedString, actualString);}@end
3: 其他一参考版本
http://stackoverflow.com/questions/5247912/saving-email-password-to-keychain-in-ios
注意使用 keychain 要导入 Security.framework
iOS 使用Keychain 保存 用户名和密码到 本地
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。