A Day In The Life

とあるプログラマの備忘録

シンプルで簡単に HTTP 通信が出来るライブラリを公開しました

iOS で HTTP 通信をするときはいつも ASIHTTPRequest を使っていました。
しかし残念なことに最近 ASIHTTPRequest の開発が終了してしまい Automatic Reference Counting(ARC) に対応する予定もないようなので自分で ARC に対応した HTTP 通信のライブラリを作成しました。
コードは github で公開しています。ライセンスはBSDライセンスです。

中身はただの NSURLConnection のラッパーです。コード量も少なく軽いライブラリです。
主な機能は以下の通りです。

  • HTTP GET POST PUT DELETE など HTTP の非同期通信
    ※現在非同期通信のみサポートしています。
  • マルチパート POST(画像送信など)
  • 自動リダイレクトのオン/オフ
  • WSSE 認証のサポート

R9HTTPRequest のクラス構造は以下のようになっています。
R9HTTPRequestのクラス図

GET で通信する

HTTP の GET 通信をする場合は以下のように URL をセットして startRequest メソッドを呼ぶだけです。リクエスト結果は setCompletionHandler メソッドのブロックで取得できます。

NSURL *URL = [NSURL URLWithString:@"http://www.apple.com"];
R9HTTPRequest *request = [[R9HTTPRequest alloc] initWithURL:URL];
// リクエスト結果の受け取り
[request setCompletionHandler:^(NSHTTPURLResponse *responseHeader, NSString *responseString){
  NSLog(@"%@", responseString);
}];
[request startRequest];

POST で通信する

HTTP の POST 通信をする場合は setHTTPMethod: メソッドに POST という文字列をセットします。addBody: forKey: メソッドでパラメータを追加することができます。

NSURL *URL = [NSURL URLWithString:@"http://posttestserver.com/post.php"];
R9HTTPRequest *request = [[R9HTTPRequest alloc] initWithURL:URL];
[request setHTTPMethod:@"POST"];
[request addBody:@"test" forKey:@"TestKey"];
[request setCompletionHandler:^(NSHTTPURLResponse *responseHeader, NSString *responseString){
  NSLog(@"%@", responseString);
}];
[request startRequest];

Multipart POST にも対応

画像のアップロードなどでよく使うマルチパート POST にも対応しています。setData: withFileName: andContentType: forKey: メソッドに NSData オブジェクトを渡すだけです。
またアップロードの進捗を知りたい場合は setUploadProgressHandler: にブロックをセットしておくと受け取ることが出来ます。

NSURL *URL = [NSURL URLWithString:@"https://posttestserver.com/post.php"];
R9HTTPRequest *request = [[R9HTTPRequest alloc] initWithURL:URL];
[request setHTTPMethod:@"POST"];
[request addBody:@"test" forKey:@"TestKey"];
// create image 
UIImage *image = [UIImage imageNamed:@"hoge"];
NSData *pngData = [[NSData alloc] initWithData:UIImagePNGRepresentation(image)];
// set image data
[request setData:pngData withFileName:@"sample.png" andContentType:@"image/png" forKey:@"file"];
[request setCompletionHandler:^(NSHTTPURLResponse *responseHeader, NSString *responseString){
  NSLog(@"%@", responseString);
}];
// Progress
[request setUploadProgressHandler:^(float newProgress){
  NSLog(@"%g", newProgress);
}];
[request startRequest];

PUT で通信する

POST と同じ要領で setHTTPMethod: メソッドに文字列 ”PUT” を渡すことで PUT 通信ができます。body へのパラメータ追加も POST と同じです。

NSURL *URL = [NSURL URLWithString:@"http://hogehogehoge.com/id/123456"];
R9HTTPRequest *request = [[R9HTTPRequest alloc] initWithURL:URL];
[request setHTTPMethod:@"PUT"];
[request addBody:@"test" forKey:@"TestKey"];
[request setCompletionHandler:^(NSHTTPURLResponse *responseHeader, NSString *responseString){
  NSLog(@"%@", responseString);
}];
[request startRequest];

DELETE で通信する

setHTTPMethod: に文字列 ”DELETE” を渡すことで DELETE 通信も出来ます。

NSURL *URL = [NSURL URLWithString:@"http://hogehogehoge.com/id/123456"];
R9HTTPRequest *request = [[R9HTTPRequest alloc] initWithURL:URL];
[request setHTTPMethod:@"DELETE"];
[request setCompletionHandler:^(NSHTTPURLResponse *responseHeader, NSString *responseString){
  NSLog(@"%@", responseString);
}];
[request startRequest];

自動リダイレクトのオン/オフもできます

通常は自動でリダイレクトしてくれますが、自動リダイレクトをオフにすることもできます。

NSURL *URL = [NSURL URLWithString:@"http://jigsaw.w3.org/HTTP/300/301.html"];
R9HTTPRequest *request = [[R9HTTPRequest alloc] initWithURL:URL];
request.shouldRedirect = NO;
[request setCompletionHandler:^(NSHTTPURLResponse *responseHeader, NSString *responseString){
  NSLog(@"%d", responseHeader.statusCode == 301);
  NSLog(@"%@", responseString);
}];
[request startRequest];

ブロックの処理はすべて UI スレッド実行されます

2012年7月1日の修正でブロックの処理をすべて UI スレッドで実行するように仕様を変更しました。completionHandler, failedHandler, uploadProgressHandler の中の処理はすべて UI スレッドで実行されます。
もちろん HTTP 通信自体は非同期で動きますのでご安心ください。

NSURL *URL = [NSURL URLWithString:@"http://www.apple.com"];
R9HTTPRequest *request = [[R9HTTPRequest alloc] initWithURL:URL];
[request setCompletionHandler:^(NSHTTPURLResponse *responseHeader, NSString *responseString){
  NSLog(@"%d", [[NSThread currentThread] isMainThread] == YES);
}];
[request startRequest];

タイムアウトの設定

タイムアウトの設定が出来ます。以前は NSMutableURLRequest の仕様で240秒以上しか設定できませんでしたが仕様変更により240秒以下も設定できるようになりました。デフォルトは60秒です。

NSURL *URL = [NSURL URLWithString:@"http://www.apple.com"];
R9HTTPRequest *request = [[R9HTTPRequest alloc] initWithURL:URL];
// タイムアウト5分
[request setTimeoutInterval:300];
[request setCompletionHandler:^(NSHTTPURLResponse *responseHeader, NSString *responseString){
  NSLog(@"%@", responseString);
}];
[request startRequest];

WSSE 認証にも対応

はてなAPI を使うのに便利な WSSE 認証にも対応しています。WSSE 認証には R9HTTPWSSERequest クラスを使用します。

NSURL *URL = [NSURL URLWithString:@"http://d.hatena.ne.jp/{はてなID}/atom/blog"];
R9HTTPWSSERequest *request = [[R9HTTPWSSERequest alloc] initWithURL:URL andUserId:@"はてなID" andPassword:@"はてなパスワード"];
[request setCompletionHandler:^(NSHTTPURLResponse *responseHeader, NSString *responseString){
  NSLog(@"%@", responseString);
}];
[request startRequest];

使い方

こちらからプログラムをダウンロードしてください。

ダウンロードしたファイルの R9HTTPRequest.h と R9HTTPRequest.m をコピーしてご自身のプロジェクトに追加してください。WSSE 認証を使う場合は Extensions フォルダをコピーしてプロジェクトに追加してください。
ファイルをコピーしたらヘッダファイルをインポートしてお使いください。

#import "R9HTTPRequest.h"

ご要望やバグがあればコメント欄にお願いします。