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. Mysql-学习笔记(==》数据库备份修复 十 四)

    CREATE DATABASE db USE db; CREATE TABLE stu( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sname VARCHAR( ...

  2. Python 2.7.9 Demo - 三元表达式

    #coding=utf-8 #!/usr/bin/python import logging; a = 'abc'; print 'Y' if isinstance(a, str) else 'N';

  3. 关于myeclipse中maven项目转换相关设置

    关于myeclipse中maven项目转换相关设置 在myeclipse菜单中,Configure->Convert to Maven Project 这个菜单 如果没有的话,需要做如下设置: ...

  4. SqlSever基础 intersect 交集 两个查询结果共有的

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

  5. C#正则表达式获取组名,按照组名输出匹配内容

    最近写了个正则表达式匹配的工具,可以按照组名输出匹配内容,还是挺方便的,代码留存一下,以后用的话,直接copy了. Regex regex = new Regex(this.textBoxRegex. ...

  6. DLL输入和输出函数—dllinport与dllexport

    Microsoft特殊处 dllimport和dllexport存储类修饰符是C语言的Microsoft特殊处扩充.这些修饰显式定义了DLL的客户界面(可执行的文件或另外的DLL).说明为dllexp ...

  7. 502 Proxy Error The proxy server received an invalid response from an upstream server

    Proxy Error The proxy server received an invalid response from an upstream server. The proxy server ...

  8. sql 相关子查询

    子查询:嵌套在其他查询中的查询. 子查询有称内部查询,而包含子查询的语句称之为外部查询 所有的子查询可以分两类,既 相关子查询和非相关子查询 1>非相关子查询是独立于外部查询的子查询,子查询总共 ...

  9. 04_IOC容器装配Bean(xml方式)

    IOC容器装配Bean(xml方式) 1.Spring 提供配置Bean三种实例化方式 1)使用类构造器实例化(默认无参数) <bean id="bean1" class=& ...

  10. FLASH CC 2015 CANVAS 导出音频问题

    1,导入音频无法成功发布(软件假死) 解决办法:先用个格式工厂重新压缩 在导入软件 发布 2, 音频 长度小于1秒(左右)的时候,导出后音频会变成  “哧”的一声,  估计和FLASH软件内部的音频编 ...