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 ...
随机推荐
- duilib\utils\utils.h(251) : error C2504: “VARIANT”: 未定义基类
转载:http://blog.csdn.net/SP_daiyq/article/details/44542939?locationNum=3 创建win32应用程序的工程文件,删除不需要的代码,只留 ...
- 摘抄--使用cos实现多个文件上传详解
在开发中常常需要上传文件,上传文件的方式有很多种,这里有一个cos实现的例子. 首先是要拷贝cos.jar包拷贝到WEB-INF/lib目录下,然后才进行编码. 创建一个可以进行自动重命名的Java文 ...
- UVA 10453 十七 Make Palindrome
Make Palindrome Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit St ...
- Mysql事件学习
出自:http://blog.chinaunix.net/uid-20639775-id-3323098.html Mysql事件学习 在系统管理或者数据库管理中,经常要周期性的执行某一个命令或者SQ ...
- XSS技巧综合
这周六会在公司分享经验和技巧,把自己的和网上的一些技巧来综合写一些,方便大家和自己: 普通的XSS,储存,反射,DOM 形成的无外乎就是输出点在html标签之间,html属性之间,成为JS代码,称为C ...
- Spark运行在eclipse_使用PyDev和pyspark
一直想在eclipse上编写Spark程序,但是仿佛是因为spark的安装包提供了PS D:\software\spark-1.6.1-bin-hadoop2.6> .\bin\spark-su ...
- Object-c : block需要注意的几点问题
摘自:http://www.cnblogs.com/ltpblog/p/3684127.html Date : 2015-12-4 1. Block定义 1) 说明: a. Block是OC中的一种数 ...
- Python基础学习笔记(九)常用数据类型转换函数
参考资料: 1. <Python基础教程> 2. http://www.runoob.com/python/python-variable-types.html 3. http://www ...
- SQL Server 临时表 Vs 表变量
开始 说临时表和表变量,这是一个古老的话题,我们在网上也找到很多的资料阐述两者的特征,优点与缺点.这里我们在SQL Server 2005\SQL Server 2008版本上通过举例子,说明临时表和 ...
- iOS - UITouch
前言 NS_CLASS_AVAILABLE_IOS(2_0) @interface UITouch : NSObject @available(iOS 2.0, *) public class UIT ...