AFNetworking 3 异步图像下载队列

AFNetworking 3 Async image download queue

我使用 AFNetworking 与我的服务器进行所有通信,所有内容都放在一个名为 'APIConnector' 的单独 class 中。

我正在尝试下载用户。当我有用户 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);
                          }];

它''works''但它只是加载最后一张图片作为所有图片,我也试过: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(组, dispatch_get_main_queue(), ^{ 成功(活动); //这个永远不会被调用 }); 我也可以控制有多少用户到达(每次通话只有 10 个),但我不知道他们有哪个 ID。

在你的第二个例子中,你有:

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);
});

不过,我必须承认,我发现对 user.profilePic.image 的提及有点令人担忧。那是 UI 套件参考吗?您不应该 UI模型对象中有 Kit 控件。


作为一个更广泛的问题,如果您不知道您可能会检索多少用户,下载所有图像可能不是内存和网络资源的明智使用。如果有 100 个用户呢?下载 100 个用户的列表会很快,但下载 100 个图像则不会。通常你应该只在你的模型中保存图像 URL,但是在 UI 需要它们之前不要请求图像(并且只下载需要的那些,例如,如果只有 12 行可见,只下载那些12 张图像)。如果您搜索“[ios] 延迟加载图像”,您可能会发现很多关于此主题的讨论。

就个人而言,鉴于您已经在使用 AFNetworking,我倾向于使用 UIImageView+AFNetworking 类别(位于 UIKit+AFNetworking 文件夹中)。这是在 UITableViewCell.

中为 UIImageView 进行惰性异步图像检索的一种非常优雅的方式