iOS 使用Keychain 保存 用户名和密码到 本地
iOS 使用Keychain 保存 用户名和密码到 本地
之前曾把一些简单的数据保存在了plist,文件,及NsuserDefault里面,
但是如果要保存密码之类的,保存在本地就很不安全了;
但是利用 Keychain 我们可以很安全的把 用户密码等信息保存在本地
1:使用苹果官方封装好的Keychain操作类
2:使用 开源的keychain操作
#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
#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 保存 用户名和密码到 本地的更多相关文章
- 使用keychain保存用户名和密码等敏感信息 KeychainItemWrapper和SFHFKeychainUtils
iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储.相对于 NSUserDefaults.文件保存等一般方式,ke ...
- android 保存 用户名和密码 设置等应用信息优化
1.传统的保存用户名,密码方式 SharedPreferences Editor editor = shareReference.edit(); editor.putString(KEY_NAME,& ...
- Android简易实战教程--第十六话《SharedPreferences保存用户名和密码》
之前在Android简易实战教程--第七话<在内存中存储用户名和密码> 那里是把用户名和密码保存到了内存中,这一篇把用户名和密码保存至SharedPreferences文件.为了引起误导, ...
- git保存用户名和密码
git保存用户名和密码 简介:tortoiseGit(乌龟git)图形化了git,我们用起来很方便,但是我们拉取私有项目的时候,每次都要输入用户名和密码很麻烦,这里向大家介绍怎么避免多少输入 试验环境 ...
- 终于解决“Git Windows客户端保存用户名与密码”的问题(转载)
add by zhj:不建议用这种方法,建议用SSH,参见 TortoiseGit密钥的配置 http://www.cnblogs.com/ajianbeyourself/p/3817364.html ...
- Git Windows客户端保存用户名和密码
解决Git Windows客户端保存用户名和密码的方法,至于为什么,就不想说了. 1. 添加一个HOME环境变量,值为%USERPROFILE% 2. 开始菜单中,点击“运行”,输入“%Home%”并 ...
- TortoiseGit+msysgit保存用户名和密码
本文以windows系统为例 保存用户名和密码 在C盘的c:\Users**qing** (或可能是C:\Users\Administrator) (替换自己的用户名)找到.gitconfig, 如果 ...
- IOS开发之----两种保存用户名和密码实现记住密码库
使用Keychain存储用户敏感信息 iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储.相对于 NSUserDe ...
- Git Windows客户端保存用户名与密码
1. 在Windows中添加一个HOME环境变量,值为%USERPROFILE%,如下图: 2. 在“开始>运行”中打开%Home%,新建一个名为“_netrc”的文件. 3. 用记事本打开_n ...
随机推荐
- js动画 无缝轮播 进度条 文字页面展示 div弹窗遮罩效果
1.无缝轮播 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.a ...
- CentOS系统识别NTFS分区的移动硬盘
第一步:下载rpmforge,下载对应的版本,就是对应CentOS版本,还有32位与64位也要对应上.rpmforge拥有4000多种CentOS的软件包,被CentOS社区认为是最安全也是最稳定的一 ...
- WinForm窗体及其控件的自适应
3步骤: 1.在需要自适应的Form中实例化全局变量 AutoSizeFormClass.cs源码在下方 AutoSizeFormClass asc = new AutoSizeFormClass ...
- Spring MVC 详解(一)
springmvc是spring的一个模块,提供web层解决方案(基于mvc设计架构),mvc是一个设计模式,在b/s系统的应用: spring 的架构 mvc设计模式 spring MVC的框架 第 ...
- qt 3 获取文件路径中的一部分
QList<QString> qlist = path.split(QRegExp("[\\\\/]")); QString FileName = qlist.at(q ...
- 【leetcode❤python】217. Contains Duplicate
#-*- coding: UTF-8 -*- class Solution(object): def containsDuplicate(self, nums): numsdic= ...
- Lucky String
Lucky String -- 微软笔试 标签(空格分隔): 算法 A string s is LUCKY if and only if the number of different charact ...
- DBCP、C3P0、Proxool 、 BoneCP开源连接池的比《转》
简介 使用评价 项目主页 DBCP DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池.DBCP可以直接的在应用程序用使用 可以设置最大和最小连接,连接等待时 ...
- jquery input选择弹框
index.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pag ...
- Java存储过程调用CallableStatement
什么是存储过程? 一个存储过程是一个可编程的函数,它在数据库中创建并保存.它可以有SQL语句和一些特殊的控制结构组成.当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有 ...