勉強目的に簡単なアプリ作ろうと思って、今個人的にとても気に入っているウェブサービス(Posterous)のiPhoneアプリを作っています。
アプリでWeb APIリクエスト・レスポンスの処理をする必要があったので、
ド素人ですが下記のような感じで初期実装してみました。
暇がある時に遊び心で触っている程度だけなので、やり方が間違っているところもたくさんあるかも知れないが、何かご指摘があれば遠慮なく突っ込んで頂けるとありがたいです。
導入したライブラリ
最初に問題になったのは、Posterous APIはBasic Authentication使っていますが、調べてみたところObjective Cにはbase64エンコードのライブラリがないことが判明しました。
そこで、Objective Resourceという良さそうなフレームワークを見つけたので、それを導入しました。(base64エンコードのためにそこまでする必要はないが、他にも勉強になりそうな部分があるフレームワークなのでそういうところを含めて入れてみました。)
XMLの解析には、GoogleのGDataXMLを使用しました。
今回は、PosterousのgetSites APIをコールします。
リクエスト処理クラス
リクエスト周りの処理はPosterousRequest.hとPosterousRequest.mにまとめました。
//
// PosterousRequest.h
//
#import <Foundation/Foundation.h>
#import "NSData+Additions.h" //Objective Resourceから
@interface PosterousRequest : NSObject {
//受信データを保存する変数
NSMutableData *receivedData;
}
@property(nonatomic,retain) NSMutableData *receivedData;
//PosterousのgetSites APIコール
- (void)getSites:(NSString*)username password:(NSString*)password;
- (void)dealloc;
//受信する時に呼び出される関数
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
@endPosterousRequest.m
//
// PosterousRequest.m
//
#import "PosterousRequest.h"
#import "PosterousAppDelegate.h"//アプリケーションのメインコントローラ
#import "GDataXMLNode.h" //GoogleのXML処理ライブラリ
@implementation PosterousRequest
//@synthesizeはクラスの基本的なgetやset関数を自動的に生成してくれます
@synthesize receivedData;
/**
* リクエスト(requestObj)に認証情報をつける関数
* http://www.wetware.co.nz/blog/2009/02/iphone-uiwebview-http-basic-authentication/
*/
- (void) addAuthToWebRequest:(NSMutableURLRequest*)requestObj username:(NSString*)username password:(NSString*)password{
//ここでobjective resourceのライブラリが使われます
NSString *authString = [[[NSString stringWithFormat:@"%@:%@", username, password] dataUsingEncoding:NSUTF8StringEncoding] base64Encoding];
authString = [NSString stringWithFormat: @"Basic %@", authString];
[requestObj setValue:authString forHTTPHeaderField:@"Authorization"];
}
/**
* リクエストを送信する
*/
- (void)sendRequest:(NSString*)address username:(NSString*)username password:(NSString*)password {
//リクエストの初期設定
NSString *urlString = [NSString stringWithFormat:address];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"POST"];
//上記のaddAuthToWebRequestで認証情報をリクエストに追加します
[self addAuthToWebRequest:request username:username password:password];
/*
Bodyなどの設定
*/
NSLog(@"connection attempted");
//PS:"@"はchar*をObjective CのNSStringにコンバートします+Unicode対応をつける
[NSURLConnection connectionWithRequest:request delegate:self];
}
//getSites APIリクエスト
-(void)getSites:(NSString*)username password:(NSString*)password {
[self sendRequest:@"https://posterous.com/api/getsites"username:username password:password];
}
//最初にレスポンスが来たとき一度だけだけ実行されます
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
//receivedDataを初期化してデータ受信の準備をする
receivedData = [[NSMutableData alloc]init];
[receivedData setLength:0];
NSLog(@"Set received data length to 0");
//レスポンスのヘッダー情報をNSLogでコンソールに出力して確認する
if ([response respondsToSelector:@selector(allHeaderFields)]) {
NSLog(@"response header");
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSDictionary *dictionary = [httpResponse allHeaderFields];
NSLog(@"%@", [dictionary description]);
}
}
//受信したデータをreceivedDataに保存する
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
}
//レスポンスが終了したときに実行されます
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *error;
NSLog(@"succeeded! received %d bytes of data", [receivedData length]);
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:receivedData options:0 error:&error];
if (doc != nil) {
/*
...
レスポンス解析
...
*/
}
/*
..
画面遷移処理など
..
*/
[doc release];
[receivedData release];
}
-(void)dealloc {
[receivedData release];
[super dealloc];
}
@end
実際にコントローラでAPIをコールするときの例:
posterousRequest = [[PosterousRequest alloc] init]; [posterousRequest getSites:self.username.text password:self.password.text]; [posterousRequest release];
以上です!