2016-05-19 1 views
1

私は自分のサーバーとのすべての通信にAFNetworkingを使用しています。すべてが「APIConnector」という別のクラスに入れられています。AFNetworking 3非同期イメージダウンロードキュー

私はユーザーをダウンロードしようとしています。私はユーザーIDを持っているときに私はURLを生成することができますが、私はそれらを受け取る前にどのユーザーが私はサーバーから得るか分からない。私が今持っているコードは次のようになります。

AFHTTPSessionManager *httpManager = [AFHTTPSessionManager manager]; 
AFHTTPSessionManager *imageManager = [AFHTTPSessionManager manager]; //Used for posting to the server 
    [httpManager POST:url parameters:dict progress:nil 
       success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
        UIImageView *imageHolder = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"placeholder"]]; 
        if (isUser) { 
         NSMutableArray *users = [NSMutableArray new]; 
         int i = 1; 
         for (id userResult in responseObject) { 
          User *user = [[User alloc] initWithId:[userResult valueForKey:@"index"] name:[userResult valueForKey:@"name"]]; 
          user.imageURL = [NSString stringWithFormat:@"%@/image/?index=%@&imgIndex=0",backendURL,user.userID]; 
          [users addObject:user]; 
          if (i == [responseObject count]) { 
           success(users); 
          } 
          i++; 
         } 

が、私はこのようにそれを試してみましたが、またこのようですが、操作とした、いくつかのことを変更し、いくつかの反復を行ってきた:

AFHTTPSessionManager *imageManager = [AFHTTPSessionManager manager]; //Used for posting to the server 
    [httpManager POST:url parameters:dict progress:nil 
       success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
        UIImageView *imageHolder = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"placeholder"]]; 
        if (isUser) { 
         NSMutableArray *users = [NSMutableArray new]; 
         int i = 1; 
         for (id userResult in responseObject) { 
          User *user = [[User alloc] initWithId:[userResult valueForKey:@"index"] name:[userResult valueForKey:@"name"]]; 
          user.imageURL = [NSString stringWithFormat:@"url to image"]; 
          [users addObject:user]; 
          if (i == [responseObject count]) { 
           success(users); 
          } 
          i++; 
         } 
         NSMutableArray *usersWithImage = [NSMutableArray new]; 
         for (int i = 0; i < users.count;i++) { 
          User *userImg = [users objectAtIndex:i]; 
          NSString *imageURL = [NSString stringWithFormat:@"%@/image/?index=%@&imgIndex=0",backendURL,userImg.userID]; 
          imageManager.responseSerializer = [AFImageResponseSerializer serializer]; 
          [imageManager GET:imageURL parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable imgResponse) { 
           User *user = userImg;[users objectAtIndex:i]; 
           user.profilePic.image = imgResponse; 
           [usersWithImage addObject:user]; 

           if (i == users.count-1) { 
            success(usersWithImage); 
           } 
          } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
           NSLog(@"Error: %@",error); 
          }]; 

それを " 「作品」」それだけですべての画像のように、私も試した中で最後の画像ロード:https://github.com/robertmryan/AFHTTPSessionOperation/同じ結果を

EDIT/ADD:

NSMutableArray *users = [NSMutableArray new]; 
dispatch_group_t group = dispatch_group_create(); 
for (id acResult in responseObject) { 
    User *user = [[User alloc]initWithId:[acResult valueForKey:@"index"] name:[acResult valueForKey:@"name"]]; 
    NSString *imageURL = [NSString stringWithFormat:@"%@/image/?index=%@&imgIndex=0",backendURL,user.userID]; 
    dispatch_group_enter(group); 
    [imageManager GET:imageURL parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
    user.imageData = UIImageJPEGRepresentation(responseObject, 1); 
    [users addObject:user]; 
    dispatch_group_leave(group);  // leave if successful 
    } 
failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
    NSLog(@"Error: %@",error); 
    dispatch_group_leave(group);  // leave if not 
    }]; 
} 

dispatch_group_notify(グループ、ディスパッチ_get_main_queue()、^ { 成功(アクティビティ); //これは決して と呼ばれます}); また、私は何人のユーザが到着するか(1コールにつき10だけ)を制御するが、どのIDを持っているのか分からない。 2番目の例では

+0

"最後のイメージをロードする"と言うとき、 'for'ループの中で' GET'が何回呼び出されているかを確認しましたか?また、 'User'オブジェクトの' profilePic'とは何ですか?画像ビューである可能性がありますが、実際にはモデル内にUIオブジェクトを配置すべきではありません。 – Rob

+0

ところで、どこに 'userID'が設定されていますか?私はあなたがユーザーのリストをダウンロードするときにそれを設定して表示されません。では、どのような 'userID'値を使うのか、これはどうやって分かりますか? – Rob

+0

最終的な観察:[Charles](http://charlesproxy.com)のようなツールをチェックすることをお勧めします。このツールは、この種の問題の診断に役立ちます。独立したツールでリクエストとレスポンスを見ることができ、問題の原因を簡単に特定できます。 – Rob

答えて

4

、あなたが持っている:すべてのダウンロードが完了したら

if (i == users.count-1) { 
    success(usersWithImage); 
} 

は、あなたが使用ディスパッチグループまたはNSOperationラッパーのいずれかを決定するために必要があり、例えば:

imageManager.responseSerializer = [AFImageResponseSerializer serializer]; // you only have to do this once 

NSMutableArray *usersWithImage = [NSMutableArray new]; 

dispatch_group_t group = dispatch_group_create(); 

for (User *user in users) { 
    NSString *imageURL = [NSString stringWithFormat:@"%@/image/?index=%@&imgIndex=0", backendURL, user.userID]; 
    dispatch_group_enter(group); 
    [imageManager GET:imageURL parameters:nil progress:nil success:^(NSURLSessionDataTask *task, id imgResponse) { 
     user.profilePic.image = imgResponse; // this line is worrying, though: What are you doing here 
     [usersWithImage addObject:user]; 
     dispatch_group_leave(group);   // leave if successful 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"Error: %@",error); 
     dispatch_group_leave(group);   // leave if not 
    }]; 
} 
dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 
    success(usersWithImage); 
}); 

Iしかし、私はuser.profilePic.imageへの参照を少し心配していることを告白する必要があります。それはUIKitリファレンスですか?モデルオブジェクトにUIKitコントロールを持たないでください。すべての画像をダウンロードする広範な問題として


、あなたが取得される可能性がありますどのように多くのユーザーがわからない場合は、メモリやネットワーク資源の賢明な利用ではないかもしれません。ユーザーが100人の場合はどうなりますか? 100人のユーザーのリストをダウンロードするのは簡単ですが、100個のイメージをダウンロードすることはできません。通常はモデルの画像URLを保存するだけですが、UIが必要とするまで画像をリクエストしないでください(たとえば、12行しか表示されず、12枚の画像のみをダウンロードするなど)。 "[ios]レイジーローディングイメージ"を検索すると、このトピックに関する多くのディスカッションが行われます。

AFNetworkingを既に使用していることを考えると、UIImageView+AFNetworkingカテゴリ(UIKit+AFNetworkingフォルダにあります)を使用する傾向があります。これは、UITableViewCellUIImageViewのための怠惰な非同期イメージ検索を行うための本当に優雅な方法です。

+0

URLを保存する方が良いですか?私はそれを試していて、ユーザーがそれを必要としたときに言いましたようにロードするだけです。しかし、私は、ユーザーが画像をすばやくブラウズするアプリケーションを作成しています(人がTinderで他のユーザーをどのようにスワイプするのかと思います)、バッチをダウンロードしてユーザーに提供できるようにしたいと思います。私はまた、OPのより広い問題に答えました。 – 4FunAndProfit

+0

個人的には、最初に作業している画像を怠惰に読み込むことに焦点を当て、正しくキャッシュされていることを確認し、すべての良いことを確認します。その後、隣接するセルの画像をダウンロードするという「予熱」問題に取り組んでいます。しかしこれを正しく行うことは、自明ではないので、私は 'UIImageView + AFNetworking'のようなものが役に立つかもしれないと考えていたのです。 – Rob

+0

はい、それは良い点です!あなたはディスパッチグループを使うべきだと思っていますか?通知者は決して解雇されないので?それは私がデバッグから知ることができるGET要求に達するが、なんらかの理由で内部に入ることはない?私はdispatch_get_main_queueで呼び出しを行う必要がありますか? NSDataとディスパッチグループを使用して最新のサンプルを更新しました – 4FunAndProfit

関連する問題