アップルのサンプルコード GenericKeychain に含まれる KeyChain のラッパー KeychainItemWrapper.m の実装が微妙だったので書きました。
kishikawakatsumi/UICKeyChainStore · GitHub
KeychainItemWrapper クラスには下記で報告されている問題や、
A-Liaison BLOG: KeychainItemWrapper を改造して、複数の Keychain Item に同時にアクセス出来るようにしてみた
下記の箇所でメモリーリークする問題があったり、使い勝手もよくないので、そのまま使うのはおすすめしません。
- (void)resetKeychainItem { OSStatus junk = noErr; if (!keychainItemData) { self.keychainItemData = [[NSMutableDictionary alloc] init]; // <= メモリーリークする!
というわけで、あたらしく書いて見ました。
使い方
- リンクするフレームワークに Security.framework を追加します。
- UICKeyChainStore.h と UICKeyChainStore.m をプロジェクトに追加します。
クラスメソッドを使って値を操作する
便利メソッドとしてクラスメソッドを用意してあります。キーと値を指定するだけで簡単に使えます。
サービス名を指定しない場合は自動的に Bundle ID がサービス名になります。
キーと値を指定して値を追加・更新する。
[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username"]; [UICKeyChainStore setString:@"password1234" forKey:@"password"]; //=> ["username" = "kishikawakatsumi", "password" = "password1234"]
サービス名を明示的に指定することもできます。
[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username" service:@"com.kishikawakatsumi"]; [UICKeyChainStore setString:@"password1234" forKey:@"password" service:@"com.kishikawakatsumi"];
値をキーチェーンから削除するにはキーを指定します。
[UICKeyChainStore removeItemForKey:@"username"]; [UICKeyChainStore removeItemForKey:@"password"];
サービス名を指定していた場合は、サービス名も含めて指定します。
[UICKeyChainStore removeItemForKey:@"username" service:@"com.kishikawakatsumi"]; [UICKeyChainStore removeItemForKey:@"password" service:@"com.kishikawakatsumi"];
KeyChainStore オブジェクトを使って値を操作する
複数の項目を追加・更新する場合は UICKeyChainStore のインスタンスを作成するほうが便利です。
NSUserDefaults のような使い勝手になります。
デフォルトのサービス名 (Bundle ID) の KeyChainStore を作成した場合。
UICKeyChainStore *store = [UICKeyChainStore keyChain]; [store setString:@"kishikawakatsumi@mac.com" forKey:@"username"]; [store setString:@"password1234" forKey:@"password"]; [store synchronize]; // Write to keychain.
サービス名を指定して KeyChainStore を作成した場合。。
UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:@"com.kishikawakatsumi"]; [store removeItemForKey:@"username"]; [store removeItemForKey:@"password"]; [store synchronize]; // Write to keychain.