LoginSignup
6
7

More than 5 years have passed since last update.

AFNetworkingでダウンロード/アップロード時にNSProgressの値が上手く取得できないとき

Last updated at Posted at 2015-07-22

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];
    }
}
6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7