2011年8月9日火曜日

OAuthConsumer.frameworkを使う(TwitterへPOST)

動機
前回の物を使ってみるため,あちらこちらのサンプルを継ぎ接ぎして(例えば)以下の様にしたら動いた..

やってみた.
フレームワークの追加

~/Library/Frameworks/のOAuthConsumer.frameworkを追加
/System/Library/Framewokrs/のSecurity.frameworkを追加


フレームワークの利用のためのHeader


#import <OAuthConsumer/OAuthConsumer.h>



インスタンス変数


OAConsumer *consumer;
OAToken *accessToken;


インスタンス変数の初期化


consumer = [[OAConsumer alloc] initWithKey:@"[Consumer Key]"
secret:@"[Consumer Secret Key]"];
accessToken= nil;

Consumer Key/Consumer Secret KeyはTwitterの開発者サイトで登録し取得する.

ConsumerKey/ConsumerSecretKeyからRequestTokenを取得へ


- (void)requestRequestToken
{
NSURL *url = [NSURL URLWithString:@"https://api.twitter.com/oauth/request_token"];

OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer
token:nil
realm:nil
signatureProvider:nil];

[request setHTTPMethod:@"POST"];

OADataFetcher *fetcher = [[[OADataFetcher alloc] init] autorelease];

[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:@selector(requestTokenTicket:didFinishWithData:)
didFailSelector:@selector(requestTokenTicket:didFailWithError:)];
}
- (void)requestTokenTicket:(OAServiceTicket *)ticket
didFinishWithData:(NSData *)data
{
if (ticket.didSucceed) {

}
}
- (void)requestTokenTicket:(OAServiceTicket *)ticket
didFailWithError:(NSError *)error
{
NSLog(@"%@", error);
}

RequestTokenから認証のWebページ(PIN)の取得へ


- (void)requestTokenTicket:(OAServiceTicket *)ticket
didFinishWithData:(NSData *)data
{
if (ticket.didSucceed) {
OAMutableURLRequest *request;
NSString *responseBody = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];

if (accessToken != nil) {
[accessToken release];
accessToken = nil;
}

accessToken = [[OAToken alloc] initWithHTTPResponseBody:responseBody];
[responseBody release];

NSURL *url = [NSURL URLWithString:@"https://api.twitter.com/oauth/authorize"];

request = [[[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer
token:accessToken
realm:nil
signatureProvider:nil] autorelease];


OARequestParameter *p0 = [[OARequestParameter alloc] initWithName:@"oauth_token"
value:accessToken.key];
NSArray *params = [NSArray arrayWithObject:p0];
[request setParameters:params];

[[NSWorkspace sharedWorkspace] openURL:[request URL]];

[p0 release];
}
else {

}

}


(デフォルトブラウザでURLが開かれる.ここではTwitterサイトでの認証であり数字キー(PIN)が手に入る

PINからAccessTokenの取得へ


- (void)authorizationWithPin:(NSString *)pin
{
OAMutableURLRequest *request;
OADataFetcher *fetcher;

NSURL *url = [NSURL URLWithString:@"https://api.twitter.com/oauth/access_token"];

request = [[[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer
token:accessToken
realm:nil
signatureProvider:nil] autorelease];


OARequestParameter *p0 = [[OARequestParameter alloc] initWithName:@"oauth_token"
value:accessToken.key];
OARequestParameter *p1 = [[OARequestParameter alloc] initWithName:@"oauth_verifier"
value:pin];
NSArray *params = [NSArray arrayWithObjects:p0, p1, nil];
[request setParameters:params];

fetcher = [[[OADataFetcher alloc] init] autorelease];

[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:@selector(accessTokenTicket:didFinishWithData:)
didFailSelector:@selector(accessTokenTicket:didFailWithError:)];

[p0 release];
[p1 release];
}
- (void)accessTokenTicket:(OAServiceTicket *)ticket
didFinishWithData:(NSData *)data
{
if (ticket.didSucceed) {

}
}
- (void)accessTokenTicket:(OAServiceTicket *)ticket
didFailWithError:(NSError *)error
{
NSLog(@"%@", error);
}

accessTokenを生成してDefaultUserInfoへ保存


- (void)accessTokenTicket:(OAServiceTicket *)ticket
didFinishWithData:(NSData *)data
{
if (ticket.didSucceed) {
NSString *responseBody = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];

if (accessToken != nil) {
[accessToken release];
accessToken = nil;
}

accessToken = [[OAToken alloc] initWithHTTPResponseBody:responseBody];
[responseBody release];

[accessToken storeInUserDefaultsWithServiceProviderName:@"NAME"
prefix:@"KEY"];

}
}


(ちなみにDeaultUserInfoから取り出すときは

accessToken= [[OAToken alloc] initWithUserDefaultsUsingServiceProviderName:@"NAME"
prefix:@"KEY"];
)

accessTokenを使ってPOSTしてみる

 NSString *message= @"Hello World!";

NSURL *url= [NSURL URLWithString:@"http://api.twitter.com/1/statuses/update.xml"];
OAMutableURLRequest *requestWithBodyParams = [[[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer
token:accessToken
realm:nil
signatureProvider:nil] autorelease];
NSString *encodedParameterPairs= [NSString stringWithFormat:@"status=%@", [message URLEncodedString]];
NSData *requestData = [encodedParameterPairs dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
[requestWithBodyParams setHTTPBody:requestData];
[requestWithBodyParams setValue:[NSString stringWithFormat:@"%d", [requestData length]]
forHTTPHeaderField:@"Content-Length"];
[requestWithBodyParams setValue:@"application/x-www-form-urlencoded"
forHTTPHeaderField:@"Content-Type"];
[requestWithBodyParams setHTTPMethod:@"POST"];

OADataFetcher *fetcher = [[[OADataFetcher alloc] init] autorelease];

[fetcher fetchDataWithRequest:requestWithBodyParams
delegate:self
didFinishSelector:@selector(apiTicket:didFinishWithData:)
didFailSelector:@selector(apiTicket:didFailWithError:)];
- (void)apiTicket:(OAServiceTicket *)ticket
didFinishWithData:(NSData *)data
{

}
- (void)apiTicket:(OAServiceTicket *)ticket
didFailWithError:(NSError *)error
{
NSLog(@"%@", error);
}


結果
http://twitter.com/#!/p_g_/status/100810688833912833

0 件のコメント: