(前回)Cocoaの日々: Keychain Services 調査 (19) 認証フロー(REST向け)実装開始
以前から Keychain item の作成とパスワードの取得は実装していたが、更新はまだだった。今回更新処理を実装する。
更新には SecKeychainItemModifyAttributesAndData を使う。
Mac Dev Center: Keychain Services Reference - SecKeychainItemModifyAttributesAndData
-[AccountManager storeLoginAccount:] にこの関数を使った更新処理を加える。
- (BOOL)storeLoginAccount:(LoginAccount*)loginAccount
{
OSStatus status;
SecKeychainItemRef itemRef = nil;
BOOL result = NO;
const char *serviceNameUTF8 = [loginAccount.serviceName UTF8String];
const char *loginIdUTF8 = [loginAccount.loginId UTF8String];
const char *passwordUTF8 = [loginAccount.password UTF8String];
status = SecKeychainFindGenericPassword(NULL,
strlen(serviceNameUTF8),
serviceNameUTF8,
strlen(loginIdUTF8),
loginIdUTF8,
NULL,
NULL,
&itemRef);
if (status == errSecItemNotFound) {
status = SecKeychainAddGenericPassword(NULL,
strlen(serviceNameUTF8),
serviceNameUTF8,
strlen(loginIdUTF8),
loginIdUTF8,
strlen(passwordUTF8),
passwordUTF8,
NULL);
if (status == errSecSuccess) {
NSLog(@"created keychain item");
result = YES;
} else {
NSLog(@"ERROR:SecKeychainAddGenericPassword:%d", status);
result = NO;
}
} else {
status = SecKeychainItemModifyAttributesAndData(itemRef,
NULL,
strlen(passwordUTF8),
passwordUTF8);
if (status == errSecSuccess) {
NSLog(@"updated keychain item");
result = YES;
} else {
NSLog(@"ERROR:SecKeychainItemModifyAttributesAndData:%d", status);
result = NO;
}
}
if (itemRef) {
CFRelease(itemRef);
}
return result;
}
最初に keychain を検索し、無ければ SecKeychainAddGenericPassword で新規作成する。存在する場合は SecKeychainItemModifyAttributesAndData を使い更新する。
ソースは GitHub からどうぞ。
KeychainSample2 at 2010-03-25 from xcatsan's SampleCode - GitHub
なお、前回 NSTextField にバインディングされたメンバ変数の同期が遅れていた件は、Bindings設定で "Continuously Updates Value" を設定することで解決した。
- - - -
次回こそは Twitpic にとりかかりたい。