AFNetworkingには、uploadTask、downloadTaskのメソッドが用意されていて、このパラメータに含まれているNSProgress
を利用することでそれぞれの進捗を取得することができます。
AFNetworkingのREADME.mdを読みながら実装すれば問題なく作成できるんですが、個人的によくうっかり間違えるポイントがあるので覚書的に残しておきます。
◆ AFNetworking
Creating an Upload Task for a Multi-Part Request, with Progress を参考にすると実装しやすいです。
NSProgressはnilで渡す
呼び出しの際に、NSProgressを参照渡しする必要がありますが、必ずnilで渡す必要があります。
間違えてNSProgress* progress = [NSProgress new]
などと宣言したものを渡すと、fractionCompletedが常に0で返ってきてしまいます。
コントロールの更新はメインスレッドで行う
当たり前なんですけどね。例えば以下のようにKVOを追加した場合。
self.progress = progress;
[progress addObserver:self
forKeyPath:@"fractionCompleted"
options:NSKeyValueObservingOptionNew
context:NULL];
以下のような形で、dispatch_asyncを書くかperformSelectorOnMainThreadなんかでメインスレッドで実行しないとリアルタイムに見た目の更新ができないので注意。
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"fractionCompleted"]) {
// ここはメインスレッドではないので、コントロールの更新は
// main_queueで行うように実装する
dispatch_async(dispatch_get_main_queue(), ^{
// ここにコントロールの更新処理
// 例えば進捗を%表示するなら、
// (int)(((NSProgress *)object).fractionCompleted * 100)%を表示
});
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}