NSURLConnectionで同期通信・非同期通信してみた

NSURLConnectionでHTTPリクエストを同期通信・非同期通信してソースを取得。
取得したソースをTextViewに表示。
文字コードは自動判定してくれないらしい。
間違った文字コードを指定するとnilが返ってくるので、日本でよく使われる文字コードを配列にして、それを総当たりでチェック。
もしどれも違ったらASCIIとする。
非同期通信+プログレスバーFlashでやるのと大体同じだった。
 
アラートにはデリゲートをつけて、何が押されたかを表示させてみた。
 
Interface Builder側は割愛。
 

ソース

test1ViewController.h
#import <UIKit/UIKit.h>

@interface test1ViewController : UIViewController {
	IBOutlet UIButton *btn1;
	IBOutlet UITextField *textfield1;
	IBOutlet UIButton *btn2;
	IBOutlet UIButton *btn3;
	IBOutlet UITextView *textview1;
	IBOutlet UIProgressView *progress;
}

-(IBAction)btn1_click;
-(IBAction)btn2_click;
-(IBAction)btn3_click;
-(IBAction)textfield1_enter;
@end

 

test1ViewController.m
#import "test1ViewController.h"

@implementation test1ViewController

NSURLConnection *connection = nil;
NSMutableData *async_data = nil;

float totalbytes;
float loadedbytes;

/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
	if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
		// Custom initialization
	}
	return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
	[super loadView];
}
*/

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidload {
	[super viewDidLoad];
}


/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
	// Return YES for supported orientations
	return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
	[super didReceiveMemoryWarning];

	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}

- (void)dealloc {
	[super dealloc];
}

// アラート表示
-(IBAction)btn1_click {
	UIAlertView *alert = [
		[UIAlertView alloc]
		initWithTitle : @"Alert!"
		message : @"HelloWorld!!"
		delegate : self
		cancelButtonTitle : @"Cancel"
		otherButtonTitles : @"OK", @"aaa", nil
	];
	[alert show];
	[alert release];
}

// アラートデリゲート
-(void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
	NSString *message = [NSString stringWithFormat:@"buttonIndex: %d", buttonIndex];
	UIAlertView *alert = [
		[UIAlertView alloc]
		initWithTitle : @"Alert!"
		message : message
		delegate : nil
		cancelButtonTitle : @"OK"
		otherButtonTitles : nil
	];
	[alert show];
	[alert release];
}

// 同期通信
-(IBAction)btn2_click {
	// hidden keyboard
	[textfield1 resignFirstResponder];

	// request
	NSURL *url = [NSURL URLWithString:textfield1.text];
	NSURLRequest *request = [NSURLRequest requestWithURL:url];
	NSURLResponse *response = nil;
	NSError *error = nil;
	NSData *data = [
		NSURLConnection
		sendSynchronousRequest : request
		returningResponse : &response
		error : &error
	];

	// error
	NSString *error_str = [error localizedDescription];
	if (0<[error_str length]) {
		UIAlertView *alert = [
			[UIAlertView alloc]
			initWithTitle : @"RequestError"
			message : error_str
			delegate : nil
			cancelButtonTitle : @"OK"
			otherButtonTitles : nil
		];
		[alert show];
		[alert release];
		return;
	}

	// response
	int enc_arr[] = {
		NSUTF8StringEncoding,			// UTF-8
		NSShiftJISStringEncoding,		// Shift_JIS
		NSJapaneseEUCStringEncoding,	// EUC-JP
		NSISO2022JPStringEncoding,		// JIS
		NSUnicodeStringEncoding,		// Unicode
		NSASCIIStringEncoding			// ASCII
	};
	NSString *data_str = nil;
	int max = sizeof(enc_arr) / sizeof(enc_arr[0]);
	for (int i=0; i<max; i++) {
		data_str = [
			[NSString alloc]
			initWithData : data
			encoding : enc_arr[i]
		];
		if (data_str!=nil) {
			break;
		}
	}
	textview1.text = data_str;
}

// 非同期通信
-(IBAction)btn3_click {
	// hidden keyboard
	[textfield1 resignFirstResponder];

	// request
	NSURL *url = [NSURL URLWithString:textfield1.text];
	NSURLRequest *request = [NSURLRequest requestWithURL:url];
	connection = [
		[NSURLConnection alloc]
		initWithRequest : request
		delegate : self
	];
	if (connection==nil) {
		UIAlertView *alert = [
			[UIAlertView alloc]
			initWithTitle : @"ConnectionError"
			message : @"ConnectionError"
			delegate : nil
			cancelButtonTitle : @"OK"
			otherButtonTitles : nil
		];
		[alert show];
		[alert release];
	}
}

// 非同期通信 ヘッダーが返ってきた
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
	// データを初期化
	async_data = [[NSMutableData alloc] initWithData:0];
	// プログレスバー更新
	totalbytes = [response expectedContentLength];
	loadedbytes = 0.0;
	[progress setProgress:loadedbytes];
}

// 非同期通信 ダウンロード中
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
	// データを追加する
	[async_data appendData:data];
	// プログレスバー更新
	loadedbytes += [data length];
	[progress setProgress:(loadedbytes/totalbytes)];
}

// 非同期通信 エラー
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
	NSString *error_str = [error localizedDescription];
	UIAlertView *alertView = [
		[UIAlertView alloc]
		initWithTitle : @"RequestError"
		message : error_str
		delegate : nil
		cancelButtonTitle : @"OK"
		otherButtonTitles : nil
	];
	[alertView show];
	[alertView release];
}

// 非同期通信 ダウンロード完了
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
	int enc_arr[] = {
		NSUTF8StringEncoding,			// UTF-8
		NSShiftJISStringEncoding,		// Shift_JIS
		NSJapaneseEUCStringEncoding,	// EUC-JP
		NSISO2022JPStringEncoding,		// JIS
		NSUnicodeStringEncoding,		// Unicode
		NSASCIIStringEncoding			// ASCII
	};
	NSString *data_str = nil;
	int max = sizeof(enc_arr) / sizeof(enc_arr[0]);
	for (int i=0; i<max; i++) {
		data_str = [
			[NSString alloc]
			initWithData : async_data
			encoding : enc_arr[i]
		];
		if (data_str!=nil) {
			break;
		}
	}
	textview1.text = data_str;
	// プログレスバー更新
	[progress setProgress:1.0];

	// memory
	[connection release];
	[async_data release];
}

// URLテキスト エンター
-(IBAction)textfield1_enter {
	// hidden keyboard
	[textfield1 resignFirstResponder];
}

@end

 

参考URL

iPhone SDKレシピ2:NSURLConnectionを使ってファイルをダウンロードする - Random Note
http://d.hatena.ne.jp/hisaboh/20081207/p2
 
MacプログラミングFAQ - NSURLConnection
http://f34.aaa.livedoor.jp/~macprog/index.php?%5B%5BNSURLConnection%5D%5D
 
UrlConnection を使ってみた - It_lives_vainlyの日記
http://d.hatena.ne.jp/It_lives_vainly/20090312/1236855251
 
Cocoa と touch, Cocoa で touch: ネットワークの接続エラーを表示する
http://cocoatouch.sblo.jp/article/27636847.html
 
UITextFieldでリターンキーが押された時にキーボードを隠す - Random Note
http://d.hatena.ne.jp/hisaboh/20081207/p1
 
NSString:stringByReplacingPercentEscapesUsingEncoding:
http://www.oomori.com/cocoafw/Foundation/NSString/stringByReplsingEncoding.html