前回、iPhoneアプリからTwitpicに画像をアップロードする方法を書いたが、そこで紹介した方法は同期処理のため、画像のアップロード中にアプリが固まってしまうという問題点がある。
この問題を解決するためには画像のアップロードを非同期で行う必要があるのだが、ASIFormDataRequestクラス自体がASIHTTPRequestクラスのサブクラスのため、NSOperationQueueを使用して以下のように簡単にそれが実現出来る。
- (void)asyncUploadPhoto { queue = [[NSOperationQueue alloc] init]; NSURL *url = [NSURL URLWithString:@"http://twitpic.com/api/upload"]; ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease]; NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"jpg"]; NSData *twitpicImage = [NSData dataWithContentsOfFile:path]; [request setPostValue:@"tomute" forKey:@"username"]; [request setPostValue:@"mypassword" forKey:@"password"]; [request setData:twitpicImage forKey:@"media"]; [request setDelegate:self]; [request setDidFinishSelector:@selector(requestDone:)]; [request setDidFailSelector:@selector(requestWentWrong:)]; // 非同期の画像アップロード開始 [queue addOperation:request]; } - (void)requestDone:(ASIFormDataRequest *)request { NSString *response = [request responseString]; NSLog(@"%@", response); } - (void)requestWentWrong:(ASIFormDataRequest *)request { NSError *error = [request error]; NSLog(@"%@", [error localizedDescription]); }
なお、画像のアップロード処理の進捗状況をユーザに伝えるために、プログレスバーを表示したいというような場合には、ASIHTTPRequestフレームワークにはASINetworkQueueという便利なクラス(NSOperationQueueのサブクラス)があって、これを使うと簡単に進捗状況を表示する事が出来る。具体的な実装は以下。
- (void)asyncUploadPhotoWithProgress { networkQueue = [[ASINetworkQueue alloc] init]; // UIProgressViewのインスタンスをセット(UIProgressView自体はInterface Builderで設置してると仮定) [networkQueue setUploadProgressDelegate:progressView]; [networkQueue setShowAccurateProgress:YES]; // 以下、goメソッドを呼ぶ処理以外は全て上のコードと同じ NSURL *url = [NSURL URLWithString:@"http://twitpic.com/api/upload"]; ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease]; NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"jpg"]; NSData *twitpicImage = [NSData dataWithContentsOfFile:path]; [request setPostValue:@"tomute" forKey:@"username"]; [request setPostValue:@"mypassword" forKey:@"password"]; [request setData:twitpicImage forKey:@"media"]; [request setDelegate:self]; [request setDidFinishSelector:@selector(requestDone:)]; [request setDidFailSelector:@selector(requestWentWrong:)]; // 非同期の画像アップロード開始 [networkQueue addOperation:request]; [networkQueue go]; // 処理開始のためにgoメソッドをコールする必要有 }
これだけで、自動的にプログレスバーをアップロードの進捗にあわせて適切に進めてくれるので、非常に便利である。
参考記事