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": @, @"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 = [username dataUsingEncoding:NSUTF8StringEncoding];
NSData *passwordData = [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 = [username dataUsingEncoding:NSUTF8StringEncoding];
NSData *passwordData = [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 = [username dataUsingEncoding:NSUTF8StringEncoding];
NSData *passwordData = [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 保存 用户名和密码到 本地的更多相关文章

  1. 使用keychain保存用户名和密码等敏感信息 KeychainItemWrapper和SFHFKeychainUtils

    iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储.相对于 NSUserDefaults.文件保存等一般方式,ke ...

  2. android 保存 用户名和密码 设置等应用信息优化

    1.传统的保存用户名,密码方式 SharedPreferences Editor editor = shareReference.edit(); editor.putString(KEY_NAME,& ...

  3. Android简易实战教程--第十六话《SharedPreferences保存用户名和密码》

    之前在Android简易实战教程--第七话<在内存中存储用户名和密码> 那里是把用户名和密码保存到了内存中,这一篇把用户名和密码保存至SharedPreferences文件.为了引起误导, ...

  4. git保存用户名和密码

    git保存用户名和密码 简介:tortoiseGit(乌龟git)图形化了git,我们用起来很方便,但是我们拉取私有项目的时候,每次都要输入用户名和密码很麻烦,这里向大家介绍怎么避免多少输入 试验环境 ...

  5. 终于解决“Git Windows客户端保存用户名与密码”的问题(转载)

    add by zhj:不建议用这种方法,建议用SSH,参见 TortoiseGit密钥的配置 http://www.cnblogs.com/ajianbeyourself/p/3817364.html ...

  6. Git Windows客户端保存用户名和密码

    解决Git Windows客户端保存用户名和密码的方法,至于为什么,就不想说了. 1. 添加一个HOME环境变量,值为%USERPROFILE% 2. 开始菜单中,点击“运行”,输入“%Home%”并 ...

  7. TortoiseGit+msysgit保存用户名和密码

    本文以windows系统为例 保存用户名和密码 在C盘的c:\Users**qing** (或可能是C:\Users\Administrator) (替换自己的用户名)找到.gitconfig, 如果 ...

  8. IOS开发之----两种保存用户名和密码实现记住密码库

    使用Keychain存储用户敏感信息 iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储.相对于 NSUserDe ...

  9. Git Windows客户端保存用户名与密码

    1. 在Windows中添加一个HOME环境变量,值为%USERPROFILE%,如下图: 2. 在“开始>运行”中打开%Home%,新建一个名为“_netrc”的文件. 3. 用记事本打开_n ...

随机推荐

  1. Python3基础 使用技巧:多行同时缩进

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  2. SqlSever基础 print 在消息中输出hello world

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  3. Python if条件语句

    1. if 条件语句 if 条件: 内容1 内容2 else: 内容3 内容4 # 一个等号是赋值(=) # 两个等号是比较(==) #不等号(!=) #if 条件1 and 条件2(并且) #if ...

  4. CodeForces 384A Coder

    Coder Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  5. CodeForces 42A Guilty — to the kitchen!

     Guilty — to the kitchen! Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & ...

  6. Flip Game poj1753

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 32961   Accepted: 14407 Description Fli ...

  7. Writing On-Error Trigger In Oracle Forms

    Suppose you want to handle an error in oracle forms and want to display custom error message for tha ...

  8. Django1.9 Python3.4出现Error loading MySQLdb

    linux Errorloading MySQLdb module: No module named MySQLdb 这是因为目前 MySQLdb 还不支持 python3.x ,开源无人维护哈 之前 ...

  9. JS如何将CST格式的日期转换为制定格式String

    <html> <body> <script type="text/javascript"> var d = new Date() dateFor ...

  10. Oracle数据库名、实例名、数据库域名、数据库服务名、全局数据库名的辨析

    我也是看着各位大婶的博客然后一点点的来学习,不求全会,留个印象 数据库名 数据库名就是一个数据库的标识,用参数DB_NAME表示. 如果一台机器上安装了多个数据库,那么每一个数据库都有一个数据库名. ...