« symfonyのfunctional testを携帯のUserAgentにしよう | メイン | Google Spreadsheet APIを使ってみた »

iPhone SDKでウェブAPIコール
このエントリーをはてなブックマークに追加 このエントリーをlivedoorクリップに追加

今さらですが最近iPhone SDKプログラミングを始めたBrandonです。

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

以上です!

ウノウでは特に最近、積極的にエンジニアを採用しています。
採用ページをご覧になり興味のある方、ぜひご応募ください。
Find Job!でも募集してます!

トラックバック

このエントリーのトラックバックURL:
http://www.unoh.net/mt32/mt-tb.cgi/1802

コメント

You couldn't pay me to ingroe these posts!

コメントを投稿


画像の中に見える文字を入力してください。