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": @42, @"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
View Code

 

  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
View Code

 

3: 其他一参考版本

http://stackoverflow.com/questions/5247912/saving-email-password-to-keychain-in-ios

 

注意使用 keychain 要导入 Security.framework

 

posted @ 2015-01-06 13:49  cocoajin  阅读(2429)  评论(0编辑  收藏  举报