Objective-CでOAuthその3

投稿者: sota 投稿日:

Pocket

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

1件のコメント

Objective-CでOAuthその2 | なんてこったいブログ · 2011年8月22日 12:07 AM

[…] 実際に使ってみるとこのままの形で使うのはなかなか使い勝手がよくないので、普段僕はブロック対応のラッパーを作って使っています。次のポストでそのラッパーについて説明します。 […]

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です