(前回)Cocoaの日々: Keychain Services 調査 (15) コーディング #4 認証フロー更新
前回のフロー図を元に実装してみる。まずは動くものを作り、汎用化は後から考えよう。
(前回のフロー図)
UI に新たに CONNECT ボタンを追加し、これを押すとフロー図の STARTから流れるようにする。
コードを見て行く。まず CONNECT ボタンが押された時の処理。
KeychainSample1AppDelegate.m
-(IBAction)connect:(id)sender
{
NSString *username = [[NSUserDefaults standardUserDefaults]
valueForKey:@"username"];
NSString *password = nil;
if (username) {
password = [[KeychainManager sharedManager]
getPasswordWithServiceName:SERVICE_NAME
accountName:username];
}
[self displayAuthenticationWindowWithUsername:username
password:password];
}
NSUserDefaults から @"username" をキーにして値を取得する。初めての認証の場合は nil 、認証済なら前回使った username が返ってくる。この username を使い、keychain からパスワードを取得する。そしてその結果を元に認証シートを表示する。
認証シートのコード。
- (void)displayAuthenticationWindowWithUsername:(NSString*)username password:(NSString*)password
{
if (username) {
[usernameText setStringValue:username];
}
if (password) {
[passwordText setStringValue:password];
}
[NSApp beginSheet:authenticateWindow
modalForWindow:window
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
今回はいきなり認証に行くのではなく、毎回認証シートを表示するようにした。前回使った username, password があればそれらが入った状態で表示される。初めての場合は空となる。
Login ボタンが押されたらシートを閉じた後、認証処理を走らせる。ここでは -[authenticateWithUsername:password:] というメソッドを呼び出している。今回はサンプルなので、このメソッドは常に YESを返す。実際はここでネットワークを介してサーバへ接続して認証を取るなどの処理を行う。
-(IBAction)login:(id)sender
{
[NSApp endSheet:authenticateWindow];
[authenticateWindow orderOut:nil];
NSString* username = [usernameText stringValue];
NSString* password = [passwordText stringValue];
BOOL result = [self authenticateWithUsername:username
password:password];
if (result) {
[[NSUserDefaults standardUserDefaults] setValue:username
forKey:@"username"];
result = [[KeychainManager sharedManager]
storePasswordWithServiceName:SERVICE_NAME
accountName:username
password:password];
[self didAuthenticate:YES];
} else {
[self displayAuthenticationWindowWithUsername:username
password:password];
}
}
認証結果を見て、成功した場合は NSUserDefaults へ username を、Keychain へ password を格納する。最後に -[didAuthenticate:] を呼び出し、成功(YES) したことを伝える。認証に失敗した場合は再び認証シートを表示する。
サンプルソースはGitHubからどうぞ
KeychainSample1 at 2010-03-18 from xcatsan's SampleCode - GitHub