iPhoneアプリからTwitter連携を行う方法②(OAuth認証後編)
前回の記事では、SA_OAuthTwitterEngineによる認証から、簡単なTweet送信ができるところまでまとめてみました。
ただ、実際のアプリ開発では、既に認証したデータを保持しておいて、毎回のログインをなくしたり、SA_OAuthTwitterEngineのdelegateを実装することで、ユーザ情報の取得を行ったりと、認証を行った後でもいくつかの処理を入れる必要があると思います。
そこで、今回は、それらの処理についてサンプルを例に解説して、ほんのちょっと実践的な動きにしてみたいと思います。
目次
認証する関数の変更
- (void)tweetFromApplication { if([[NSUserDefaults standardUserDefaults] objectForKey: @"authData"]==nil){ //このコードがないと、複数アカウント対応や、アカウントの削除の時に、 //_engineは認証されているのに、認証キーが無い状態になってしまう。 _engine = nil; [_engine release]; } // Twitter Initialization if(!_engine){ _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self]; _engine.consumerKey = kOAuthConsumerKey; _engine.consumerSecret = kOAuthConsumerSecret; } //OAuth tokenがあるかどうかを判断。 if(![_engine isAuthorized]){ UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self]; if (controller){ //これで、Login画面が表示される。 //上記のインスタンス化で、すでにdelegateはselfになっている。 [viewController presentModalViewController: controller animated: YES]; }else{} } if([_engine isAuthorized]){ //UserDefaultsにOAuthKeyがあるときは、engineの初期化後、ここに来る。 //If there is OAuthKey in UserDefaults, executed this code. CCLOG(@"%@",[_engine getUserInformationFor:[_engine username]]); //change scene to tweet. We are already authenticated. [[CCDirector sharedDirector] replaceScene: [CCTransitionSlideInR transitionWithDuration:0.4 scene:[MyTweetScene node]]]; } }
SA_OAuthTwitterControllerのdelegateを実装
SA_OAuthTwitterControllerは主にTwitterへの認証を行うログイン画面の制御を行うクラスです。そのため、このクラスのdelegateのmethodは、ログインの成功、失敗、キャンセルなどの動きをハンドリングすることができます。
#pragma mark SA_OAuthTwitterController - (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username{ CCLOG(@"%@",username); //If We are authenticated, try to get this user's Information. //When can get user info, will be called below method.... //When can get user info, will be called below method.... //- (void)userInfoReceived:... CCLOG(@"%@",[_engine getUserInformationFor:username]); } - (void) OAuthTwitterControllerFailed: (SA_OAuthTwitterController *) controller{ CCLOG(@"OAuthTwitterControllerFailed"); } - (void) OAuthTwitterControllerCanceled: (SA_OAuthTwitterController *) controller{ CCLOG(@"canceled"); //TwitterのLogin画面がCancelで閉じられたとき。 }
TwitterEngineDelegateのdelegateを実装
TwitterEngineDelegateは、主にTwitterAPIとの通信をやり取りするクラスです。基本的には、Tweetの送信やその成功、失敗などをハンドリングします。
#pragma mark SA_OAuthTwitterEngineDelegate - (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username { //We can store user authKey in UserDefaults. //UserDefaultsに、認証したデータを保持しておくことができます。 //保持しておくと、次回は下のcachedTwitterOAuthDataForUsernameが //呼ばれて、値があれば、保存されている値が利用されます。 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject: data forKey: @"authData"]; [defaults synchronize]; } - (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username { return [[NSUserDefaults standardUserDefaults] objectForKey: @"authData"]; } - (void) requestSucceeded: (NSString *) requestIdentifier { CCLOG(@"Request %@ succeeded", requestIdentifier); } - (void) requestFailed: (NSString *) requestIdentifier withError: (NSError *) error { CCLOG(@"Request %@ failed with error: %@", requestIdentifier, error); }
TwitterEngineDelegateのdelegateを実装追加
TwitterEngineDelegateのdelegateを実装を追加して、ユーザ情報、プロファイル画像を取得したりすることもできます。以下はその実装例です。TwetterのProfileのiconなどは、取得してUserDefaultsなどに保持しておくと、アプリを利用する人が分かりやすいかもしれませんね。
- (void)userInfoReceived:(NSArray *)userInfo forRequest:(NSString *)connectionIdentifier { NSString *strUserInfo = [[userInfo objectAtIndex:0] objectForKey:@"profile_image_url"]; CCLOG(@"%@", strUserInfo); [_engine getImageAtURL:strUserInfo]; } - (void)imageReceived:(UIImage *)image forRequest:(NSString *)identifier { NSLog(@"Got an image:%@",image); // What goes here? Or elsewhere? [MyGameUtil storeCachedProfileImage:image]; [[CCDirector sharedDirector] replaceScene: [CCTransitionSlideInR transitionWithDuration:0.4 scene:[HighlowTweetScene node]]]; }
複数アカウント時の_engineの初期化は逆じゃないですか?
_engine = nil;
[_engine release];
↓
if(_engine)
[_engine release];
_engine = nil;