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": @, @"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://*.com/questions/5247912/saving-email-password-to-keychain-in-ios

注意使用 keychain 要导入 Security.framework

上一篇:python的项目结构


下一篇:L333 Should You Listen to Music While You Work?