&tag(GTMOAuth); *目次 [#qea7a900] #contents *参考情報 [#t3892a5a] -[[gtm-oauth - Google Toolbox for Mac - OAuth Controllers - Google Project Hosting:http://code.google.com/p/gtm-oauth/]]…Google製のOAuthライブラリ。 -[[GTMOAuthでTwitterなどのOAuthを行う方法 - Awaresoft:http://www.awaresoft.jp/ios-dev/item/90-gtmoauth]] -[[予定外 [iOS5/ARC対応] iOSでTwitterクライアント その1 (準備編):http://homepie.blog.shinobi.jp/Entry/32/]] -[[予定外 [iOS5/ARC対応] iOSでTwitterクライアント その2 (サインイン):http://homepie.blog.shinobi.jp/Entry/33/]] -[[予定外 [iOS5/ARC対応] iOSでTwitterクライアント その3 (タイムライン取得):http://homepie.blog.shinobi.jp/Entry/34/]] -[[予定外 [iOS5/ARC対応] iOSでTwitterクライアント その4 (ツイート投稿):http://homepie.blog.shinobi.jp/Entry/35/]] *基本 [#x97244e3] -TwitterのWebページをUIWebViewで表示しOAuth認証するライブラリ。 -OAuthするだけなので、Twitterでつぶやくとかそういう機能はない。 *サンプル: OAuthSampleTouch [#a5991874] **基本 [#yd2b2ddb] -GTMOAuthをダウンロードしたフォルダの中にある、OAuthSampleTouchというのがiOS用のサンプル。2012/07/24(火)現在のものなので将来的に変わる可能性あり。 -ビルドしてもそのまま動かないので、OAuthSampleRootViewControllerTouch.mを修正する。 -以下TwitterのOAuth認証を利用する場合の修正方法を説明。 -Twitterアプリは予めdev.twitter.comで登録しておく。認証タイプはBrowserにしておかないとだめ(コールバックURLにURLが入っているかどうかで判定しているらしい。つまりURLが入っていればBrowser。入ってなければデスクトップ扱い。)。 ** OAuthSampleRootViewControllerTouch.mのauthForTwitterの修正 [#r81b0d6b] -ConsumerKey, ConsumerSecretを自分のTwitterアプリのものに修正する(これはTwitterにアプリを登録すれば表示される)。 #pre{{ - (GTMOAuthAuthentication *)authForTwitter { //以下を修正 NSString *myConsumerKey = @"YourConsumerKey"; NSString *myConsumerSecret = @"YourConsumerSecret"; if ([myConsumerKey length] == 0 || [myConsumerSecret length] == 0) { return nil; } GTMOAuthAuthentication *auth; auth = [[[GTMOAuthAuthentication alloc] initWithSignatureMethod:kGTMOAuthSignatureMethodHMAC_SHA1 consumerKey:myConsumerKey privateKey:myConsumerSecret] autorelease]; [auth setServiceProvider:kTwitterServiceName]; return auth; } }} **signInToTwitterの修正 [#jacafd5e] -OAuthに必要なURLを修正する。変わる可能性があるのでTwitterアプリページに表示されるものをコピペしたほうがよい(httpじゃなくhttpsとか)。 -scopeはnilでいいらしい。 -setCallbackで設定するURLはダミーでいいらしい。 -setBrowserCookiesURLでセットするURLはブラウザのCookieを消去するURL。二回目表示したときにログイン状態にならないようにする。これもOAuthのURLに併せてhttpsバージョンにしたほうがいいっぽい。 #pre{{ - (void)signInToTwitter { [self signOut]; NSURL *requestURL = [NSURL URLWithString:@"https://api.twitter.com/oauth/request_token"]; NSURL *accessURL = [NSURL URLWithString:@"https://api.twitter.com/oauth/access_token"]; NSURL *authorizeURL = [NSURL URLWithString:@"https://api.twitter.com/oauth/authorize"]; GTMOAuthAuthentication *auth = [self authForTwitter]; if (auth == nil) { // perhaps display something friendlier in the UI? NSAssert(NO, @"A valid consumer key and consumer secret are required for signing in to Twitter"); } //これはダミーでいいらしい [auth setCallback:@"http://www.example.com/OAuthCallback"]; NSString *keychainItemName = nil; if ([self shouldSaveInKeychain]) { keychainItemName = kTwitterKeychainItemName; } // Display the autentication view. GTMOAuthViewControllerTouch *viewController; viewController = [[[GTMOAuthViewControllerTouch alloc] initWithScope:nil //scopeはNULLに language:nil requestTokenURL:requestURL authorizeTokenURL:authorizeURL accessTokenURL:accessURL authentication:auth appServiceName:keychainItemName delegate:self finishedSelector:@selector(viewController:finishedWithAuth:error:)] autorelease]; // Cookieを消去するURLこれもhttpsバージョンにしたほうがよいのかな? [viewController setBrowserCookiesURL:[NSURL URLWithString:@"https://api.twitter.com/"]]; [[self navigationController] pushViewController:viewController animated:YES]; } }} **動作確認 [#b8579aa4] -Twitterを選び、[Sign In]ボタンを押す。 #ref(start.png) -Twitterアカウントを入力。 #ref(twitter.png) -AccessTokenが表示される。デバッガ出力に動作確認として認証が必要なステータスが出力される。 #ref(finish.png) **動作の流れ解説 [#s24e0a6d] ***認証開始 [#t1690249] -[Sign in]ボタンを押すとsignInOutClicked→signInToTwitterと呼ばれる。 -signInToTwitterでは、GTMOAuthViewControllerTouchが呼ばれる。このビューコントローラーはフレームワーク側にある。TwitterのWeb認証が行われる。 ***認証成功 [#m952e8f4] -Web認証が終わるとGTMOAuthSignIn.mのaccessFetcher:finishWithData:error:が呼ばれる。 #pre{{ - (void)accessFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error { [self setPendingFetcher:nil fetchType:nil]; if (error) { [self invokeFinalCallbackWithError:error]; } else { // we have an access token [auth_ setKeysForResponseData:data]; [auth_ setHasAccessToken:YES]; #if !GTM_OAUTH_SKIP_GOOGLE_SUPPORT if (shouldFetchGoogleUserInfo_ && [[auth_ serviceProvider] isEqual:kGTMOAuthServiceProviderGoogle]) { // fetch the user's information from the Google server [self fetchGoogleUserInfo]; } else { // we're not authorizing with Google, so we're done [self invokeFinalCallbackWithError:nil]; } #else [self invokeFinalCallbackWithError:nil]; #endif } } }} - [auth_ setKeysForResponseData:data]は、GTMOAuthAuthenticationのメソッドで_authオブジェクトに必要な情報がセットされる。 #pre{{ - (void)setKeysForResponseDictionary:(NSDictionary *)dict { NSString *token = [dict objectForKey:kOAuthTokenKey]; if (token) { [self setToken:token]; } NSString *secret = [dict objectForKey:kOAuthTokenSecretKey]; if (secret) { [self setTokenSecret:secret]; } NSString *callbackConfirmed = [dict objectForKey:kOAuthCallbackConfirmedKey]; if (callbackConfirmed) { [self setCallbackConfirmed:callbackConfirmed]; } NSString *verifier = [dict objectForKey:kOAuthVerifierKey]; if (verifier) { [self setVerifier:verifier]; } NSString *provider = [dict objectForKey:kServiceProviderKey]; if (provider) { [self setServiceProvider:provider]; } NSString *email = [dict objectForKey:kUserEmailKey]; if (email) { [self setUserEmail:email]; } NSString *verified = [dict objectForKey:kUserEmailIsVerifiedKey]; if (verified) { [self setUserEmailIsVerified:verified]; } } }} -次にGTMOAuthSignIn.mのaccessFetcher:finishWithData:error:からGTMOAuthViewControllerTouchのsaveParamsToKeychainForNameが呼ばれ、認証情報がキーチェインに保存される。 #pre{{ + (BOOL)saveParamsToKeychainForName:(NSString *)appServiceName authentication:(GTMOAuthAuthentication *)auth { [self removeParamsFromKeychainForName:appServiceName]; // don't save unless we have a token that can really authorize requests if (![auth hasAccessToken]) return NO; // make a response string containing the values we want to save NSString *password = [auth persistenceResponseString]; GTMOAuthKeychain *keychain = [GTMOAuthKeychain defaultKeychain]; return [keychain setPassword:password forService:appServiceName account:kGTLOAuthAccountName error:nil]; } }} -最後に、GTMOAuthSignIn.mのaccessFetcher:finishWithData:error:から、viewController:finishedWithAuth:errorが呼ばれる。成功の場合doAnAuthenticatedAPIFetchが呼ばれ、そこでTwitterで認証されたアカウントのタイムラインがテスト用に表示される(出力ウィンドウに)。 ***保存済みの認証情報の利用 [#nfac1dab] -次のように初期化する。 -次のように初期化する。kTwitterKeychainItemNameは当然保存時に指定したキーチェイン名と同じにすること。 #pre{{ _auth = [[GTMOAuthAuthentication alloc] initWithSignatureMethod:kGTMOAuthSignatureMethodHMAC_SHA1 consumerKey:kTwitterConsumerKey privateKey:kTwitterConsumerSecret]; BOOL didAuth = [GTMOAuthViewControllerTouch authorizeFromKeychainForName:kTwitterKeychainItemName authentication:_auth]; NSLog(@"didAuth=%d", didAuth); }} *自前のプロジェクトに組み込む [#j88b6a5d] -Security.frameworkとSystemConfiguration.frameworkの追加が必要。 -GTMHTTPFetcherLogging.mでSBJsonを使っている。