NSURLConnectionを使ってサーバーにデータを送信する

データの受信ができたところで(なぜか1行目だけログに表示されないというバグがまだ未解決だが)、データの送信も試してみます。

GETでデータを送信

データの送信には様々なやり方があるが、まずはシンプルにGETでクエリ文字列で値を送信してみる。ただのGETリクエストなので、先ほどのコードで動作して当然ではあるが、一応実験。
サーバー側に設置したPHPスクリプト

nctest:param=

iPhone側、送信部分

- (IBAction)openUrl:(id)sender{
	MyNetworkConnector* connector = [[MyNetworkConnector alloc] initWithDelegate:self];
	[connector openUrl:@"http://syokoe.net/nc1.php?param=abcdef"];
}

実行結果(一部)

2009-11-29 14:19:59.795 network_connection[2259:207] nctest:param=abcdef

POSTでデータを送信

GETでは送信できるデータ量に限界があるので、今度はPOSTでデータを送信してみる。
POSTで通信を行いたい場合は、URLリクエストの生成部分を変更する。NSURLRequestの代わりにNSMutableURLRequestを使い、setHTTPMethodメソッドでメソッドをPOSTに、setHTTPBodyメソッドで送信するデータを設定する。

req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]
						   cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[req setHTTPMethod:@"POST"];	//メソッドをPOSTに指定します
[req setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];		//パラメータを渡します

MyNetworkConnectorを改造し、GETとPOSTでリクエストを送ることができるようにする。ここでは可読性をあげるためにパラメータのURLエンコーディングは省略する。パラメータで送る文字列は既にURLエンコードされ、param1=a&param2=b…という形になっているものとする。
MyNetworkConnector.h

//
//  MyNetworkConnector.h
//  network_connection
//
#import
typedef enum {
	RequestMethodGet,
	RequestMethodPost
} MyNetworkConnectorRequestMethod;
@interface MyNetworkConnector : NSObject {
	NSMutableData *receivedData;
	NSStringEncoding encoding;
	id _delegate;
	NSString* receivedString;
}
@property (readonly) NSString* receivedString;
- (id)initWithDelegate:(id)delegate;
- (void)openUrl:(NSString*)urlString;
- (void)openUrl:(NSString*)urlString method:(MyNetworkConnectorRequestMethod)method params:(NSString*)params;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
@end

MyNetworkConnector.mm(一部のみ)

- (void)openUrl:(NSString*)urlString{
	//メソッドが指定されなかった場合はGETで処理するようにします
	[self openUrl:urlString method:RequestMethodGet params:@""];
}
//注意:ここではパラメータとして送る文字列は既にURLエンコードされてparam1=a&param2=b...という形式になっていることが
//前提です
- (void)openUrl:(NSString*)urlString method:(MyNetworkConnectorRequestMethod)method params:(NSString*)params{
	//受信したデータを保存するための変数を初期化します
	receivedData = [[NSMutableData alloc] initWithLength:1];
	if (receivedString != nil){
		[receivedString release];
		receivedString = nil;
	}
	//1.URLリクエストを作ります
	NSMutableURLRequest *req;
	switch (method) {
		case RequestMethodPost:{	//POSTの場合
			req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]
								   cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
			[req setHTTPMethod:@"POST"];	//メソッドをPOSTに指定します
			[req setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];		//パラメータを渡します
			break;
		}
		default:{	//POST以外のメソッドはGETとして扱います
			//パラメータが指定されている場合はURLにアペンドします
			NSString *paramsAppendedUrlString;
			if (params != nil && [params length] > 0) {
				paramsAppendedUrlString = [NSString stringWithFormat:@"%@?%@", urlString, params];
			}else{
				paramsAppendedUrlString = urlString;
			}
			req = [NSURLRequest requestWithURL:[NSURL URLWithString:paramsAppendedUrlString]
								   cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
			break;
		}
	}
	//2.HTTP通信を開始させます
	NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
	if (conn == nil) {
		[_delegate performSelector:@selector(receiveFailed:)];
	}
}

POSTでパラメータを送信するテスト

- (IBAction)openUrl:(id)sender{
	MyNetworkConnector* connector = [[MyNetworkConnector alloc] initWithDelegate:self];
	[connector openUrl:@"http://localhost/nc2.php" method:RequestMethodPost params:@"param=deadbeef"];
}

受信側PHPスクリプト

nctest:param=

実行結果(一部のみ抜粋)

2009-11-29 14:56:35.016 network_connection[2714:207] nctest:param=deadbeef

参考資料:

  1. NSURLConnection – Using POST – Mac Forums
Pocket

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です