iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用。从ios 3。0开始,跨程序分享keychain变得可行。
如何需要在应用里使用使用keyChain,我们需要导入Security.framework ,keychain的操作接口声明在头文件SecItem.h里。直接使用SecItem.h里方法操作keychain,需要写的代码较为复杂,为减轻咱们程序员的开发,我们可以使用一些已经封装好了的工具类,下面我会简单介绍下我用过的两个工具类:KeychainItemWrapper和SFHFKeychainUtils。
KeychainItemWrapper是apple官方例子“GenericKeychain”里一个访问keychain常用操作的封装类,在官网上下载了GenericKeychain项目后,只需要把“KeychainItemWrapper.h”和“KeychainItemWrapper.m”拷贝到我们项目,并导入Security.framework 。KeychainItemWrapper的用法:
/** 初始化一个保存用户帐号的KeychainItemWrapper */
KeychainItemWrapper
*wrapper
=
[
[KeychainItemWrapper alloc
] initWithIdentifier
:@
"Account Number"
accessGroup
:@
"YOUR_APP_ID_HERE.com.yourcompany.AppIdentifier"
]
;
//保存帐号
[wrapper setObject
:@
"<帐号>" forKey
:
(id
)kSecAttrAccount
]
;
//保存密码
[wrapper setObject
:@
"<帐号密码>" forKey
:
(id
)kSecValueData
]
;
//从keychain里取出帐号密码
NSString
*password
=
[wrapper objectForKey
:
(id
)kSecValueData
]
;
//清空设置
[wrapper resetKeychainItem
]
;
其中方法“- (void)setObject:(id)inObject forKey:(id)key;”里参数“forKey”的值应该是Security.framework 里头文件“SecItem.h”里定义好的key,用其他字符串做key程序会崩溃!
SFHFKeychainUtils是另一个封装了KeyChain简单操作的第三方类库,使用上比KeychainItemWrapper要简单点,SFHFKeychainUtils只提供了获取、保存和删除三个方法:
#import
<UIKit
/UIKit.
h
>
@
interface SFHFKeychainUtils
: NSObject
{
}
/** 从Keychain里获取用户密码
*param username 用户名
*param serviceName 服务名
*return NSString 用户名对应的密码
*/
+
(NSString
*
) getPasswordForUsername
:
(NSString
*
) username andServiceName
:
(NSString
*
) serviceName error
:
(NSError
**
) error
;
/**
*把用户的密码保存到Keychain里
*@param username 用户名
*@param password 要保存的密码
*@param serviceName 本条keychains所属的服务(组)
*return BOOL 是否存储成功
*/
+
(BOOL
) storeUsername
:
(NSString
*
) username andPassword
:
(NSString
*
) password forServiceName
:
(NSString
*
) serviceName updateExisting
:
(BOOL
) updateExisting error
:
(NSError
**
) error
;
/**
* 删除某个用户信息
*param username 用户名
*param serviceName 用户所属的服务(组)
*return BOOL 是否删除成功
*/
+
(BOOL
) deleteItemForUsername
:
(NSString
*
) username andServiceName
:
(NSString
*
) serviceName error
:
(NSError
**
) error
;
@end
使用方法:
#define ServiceName @
"com.mycompany.yourAppServiceName"
NSError
*error
;
NSString
*userName
= @
"<用户名>"
;
NSString
*password
= @
"<用户密码>"
;
/** 保存用户的密码*/
BOOL saved
=
[SFHFKeychainUtils storeUsername
:userName
andPassword
:password
forServiceName
:ServiceName
updateExisting
:YES
error
:&error
]
;
if
(
!saved
)
{
NSLog
(@
"保存密码时出错:%@", error
)
;
}
error
= nil
;