OAuthConsumerの標準のデリゲート/セレクタを使う形の使い方は、実際に使ってみると可読性の低いコードになってしまったり、セレクタの名前を間違えてしまったりなどミスが発生しがちなので、OAuthConsumerをブロックに対応させるクラスを作りました。
例によって、使うときは無保証/自己責任で注意して使ってください。
SYOAuthクラスの使い方
[SYOAuth requestWithURL:@"http://example.com/foo" isPost:NO consumerKey:consumerKey consumerSecret:consumerSecret tokenKey:token tokenSecret:secret completionHandler:^(NSString *result, NSError *error) { if (error == nil) { NSLog(@"Result: %@", result); } else { NSLog(@"Error: %@", error); } }];
SYOAuthクラスでは、コールバックをブロックの形で指定しています。コーディングの量が減るのに加えて、メソッドチェーンが書きやすくなります。実際、外部サービスを使うような場合というのは「tokenの有効性を認証する -> 実際に情報取得等のapiを叩く」など、メソッドチェーンが沢山登場するので、それをデリゲート/セレクタ指定の形で実装するとコードが非常に汚くなってしまいます。
加えて、OAConsumerやOATokenのインスタンス生成のコードを毎回いれるのも面倒臭いので、引数で一発で指定できるようにしています。
isPost引数にYESを渡すとリクエストをPOSTで投げます。
ソースコード
SYOAuth.h
// // SYOAuth.h // // Created by Sota Yokoe on 11/08/20. // Copyright (c) 2011 __MyCompanyName__. All rights reserved. // nantekottai.com // #import #import "OAuthConsumer.h" @interface SYOAuth : NSObject { id completionHandler_; OADataFetcher *fetcher; } + (void)requestWithURL:(NSString*)urlString isPost:(BOOL)isPost consumerKey:(NSString*)consumerKey consumerSecret:(NSString*)consumerSecret tokenKey:(NSString*)tokenKey tokenSecret:(NSString*)tokenSecret completionHandler:(void (^)(NSString* result, NSError* error))completionHandler; @end
SYOAuth.m
// // SYOAuth.m // // Created by Sota Yokoe on 11/08/20. // Copyright (c) 2011 __MyCompanyName__. All rights reserved. // #import "SYOAuth.h" @interface SYOAuth() @property (copy) id completionHander; @property (retain) OADataFetcher *fetcher; @end @implementation SYOAuth @synthesize completionHander = completionHandler_, fetcher; - (void)dealloc { self.completionHander = nil; self.fetcher = nil; [super dealloc]; } + (void)requestWithURL:(NSString*)urlString isPost:(BOOL)isPost consumerKey:(NSString*)consumerKey consumerSecret:(NSString*)consumerSecret tokenKey:(NSString*)tokenKey tokenSecret:(NSString*)tokenSecret completionHandler:(void (^)(NSString* result, NSError* error))completionHandler { SYOAuth* anInstance = [[[SYOAuth alloc] init] autorelease]; anInstance.completionHander = completionHandler; OAConsumer *consumer = [[[OAConsumer alloc] initWithKey:consumerKey secret:consumerSecret] autorelease]; OAToken* token = tokenKey ? [[[OAToken alloc] initWithKey:tokenKey secret:tokenSecret] autorelease] : nil; OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString] consumer:consumer token:token realm:nil signatureProvider:nil] autorelease]; if (isPost) [request setHTTPMethod:@"POST"]; anInstance.fetcher = [[[OADataFetcher alloc] init] autorelease]; [anInstance.fetcher fetchDataWithRequest:request delegate:[anInstance retain] didFinishSelector:@selector(requestTokenTicket:didFinishWithData:) didFailSelector:@selector(requestTokenTicket:didFailWithError:)]; } - (void)requestTokenTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data { self.fetcher = nil; NSString *responseBody = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; void (^callback)(NSString* result, NSError* error) = self.completionHander; callback(responseBody, nil); [self release]; } - (void)requestTokenTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error { void (^callback)(NSString* result, NSError* error) = self.completionHander; callback(nil, error); [self release]; } @end
「Objective-CでOAuthその3」への1件のフィードバック