iPhoneアプリからTwitpicに画像をアップロードする方法(非同期編)

前回、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メソッドをコールする必要有
}

これだけで、自動的にプログレスバーをアップロードの進捗にあわせて適切に進めてくれるので、非常に便利である。


参考記事