我使用AFNetworking进行与服务器的所有通信,所有内容都放在一个名为“APIConnector'”的单独类中。
我试图下载用户。当我有用户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);
}];
它&#39;&#39;&#39;&#39;&#39;&#39;但它只是加载最后一张图像作为所有图像,我也试过: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(group,dispatch_get_main_queue(),^ { 成功(活动); //从未调用过 }); 此外,我可以控制有多少用户到达(每次通话只有10个),但我不知道他们有哪个ID。
答案 0 :(得分: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);
});
但是,我必须承认,我发现user.profilePic.image
的提法有点令人担忧。这是UIKit参考吗?你不应该在模型对象中拥有UIKit控件。
作为一个更广泛的问题,如果您不知道可能要检索的用户数量,那么下载所有图像可能不是明智地使用内存和网络资源。如果有100个用户怎么办?下载100个用户的列表将很快,但下载100个图像不会。通常,您只需将图片网址保存在模型中,但不要在图片需要之前请求图片(并且只下载所需的图片,例如,如果只有12行可见,则只下载这12张图片)。如果您搜索&#34; [ios]延迟加载图片&#34;,您可能会在此主题上找到很多讨论。
就个人而言,鉴于您已经在使用AFNetworking,我倾向于使用UIImageView+AFNetworking
类别(位于UIKit+AFNetworking
文件夹中)。这是一种非常优雅的方法,可以对UIImageView
中的UITableViewCell
进行延迟异步图像检索。