MPOAuthConnectionでHTTP ResponseのStatus Codeなどを取得する

OAuthが実装された外部APIを、MPOAuthAPIクラスのperformMethodメソッドで呼んだ場合、performMethodメソッドのandAction引数に指定したメソッドがコールバックされます。コールバックされるメソッドの第一引数は、「(NSURL *)inURL」で、第二引数は、「withResponseString:(NSString *)inString」です。例えば、サンプルアプリのMOAuthMobileにあるRootViewController.mでは次のようになっています。

- (void)_methodLoadedFromURL:(NSURL *)inURL withResponseString:(NSString *)inString {
  textOutput.text = inString;
}

このメソッドは、MPOAuthAPIRequestLoader.mのconnectionDidFinishLoadingメソッド内で呼ばれ、Request URLとエンコードされたResponse HTTP Bodyを返すようになっています。

  [_target performSelector:_action withObject:self.oauthRequest.url withObject:self.responseString];

しかし、Twitter APIの場合、HTTP ResponseのStatus Codeも重要な意味があります。

HTTP ResponseのStatus Codeなどを取得する為、コールバックされるメソッドの第一引数をNSURLからMPOAuthURLResponseに変えようかと。そこで、MPOAuthAPIInternalClientと同様のやり方で、「MPOAuthAPIExtenedClient」というプロトコルを追加する形にしました。この方法は、MPOAuthAPIExtendClientにクラス(例えばRootViewController.m)を準拠させることになるので、クラス内で実装したperformMethodメソッドのコールバック関数の第一引数を全て変更しなければいけませんが、MPOAuthConnection本体や他のソースには影響が少ないのではと思いました。


MPOAuthAPIRequestLoader.m

- (void)_interrogateResponseForOAuthData;
@end

@protocol MPOAuthAPIInternalClient;
@protocol MPOAuthAPIExtenedClient;

@implementation MPOAuthAPIRequestLoader


MPOAuthAPIRequestLoader.m(connectionDidFinishLoadingメソッド内)

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
  [self _interrogateResponseForOAuthData];
  if (_action) {
    if ([_target conformsToProtocol:@protocol(MPOAuthAPIInternalClient)]) {
      [_target performSelector:_action withObject:self withObject:self.data];
    } else if([_target conformsToProtocol:@protocol(MPOAuthAPIExtenedClient)]) {
      [_target performSelector:_action withObject:self.oauthResponse withObject:self.responseString];
    } else {
      [_target performSelector:_action withObject:self.oauthRequest.url withObject:self.responseString];
    }
  }
}


後はRootViewController.hでMPOAuthAPIExtenedClientプロトコルを設定します。コールバックするメソッドの第一引数をMPOAuthURLResponseに変え、NSHTTPURLResponseにキャストすればStatus Codeを取得できます。


RootViewController.h

@protocol MPOAuthAPIExtenedClient
@end

@interface RootViewController : UIViewController <MPOAuthAPIExtenedClient> {


RootViewController.m(文頭で、「#import "MPOAuthURLResonse.h"」を忘れずに。)

- (void)_methodLoadedFromURL:(MPOAuthURLResponse *)inResponse withResponseString:(NSString *)inString {
  NSHTTPURLResponse *httpURLResponse = (NSHTTPURLResponse *)inResponse.urlResponse;
  MPLog(@"Status Code: %d", [httpURLResponse statusCode]);
  MPLog(@"%@", [httpURLResponse allHeaderFields]);
  textOutput.text = inString;
}

Status Code以外にも、Twitterの場合、X-RateLimit-Limitなど(http://apiwiki.twitter.com/Rate-limiting)、投稿制限値がHTTP Headerで戻ってきますので、NSHTTPURLResponseクラスのallHeaderFieldsメソッドで取得できました。


この他、MPOAuthRequestLoaderクラスのdidFailWithErrorメソッドを見ると、正常終了した場合と同じメソッドがコールバックされるようになっているので、失敗した場合は違うメソッドをコールバックできるように修正したりしています。そろそろ、diffとって、patch作った方がいいのかな。