勉強目的に簡単なアプリ作ろうと思って、今個人的にとても気に入っているウェブサービス(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; @end
PosterousRequest.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];
以上です!