Download images to UICollectionView via AFNetworking

739 Views Asked by At

I'm new in iOS programming. So I've newbie question. I'm getting started with AFNetworking 2 and that is the task:

I've a request. Its response is the part of the second request. It means that I have to wait untill first request ends. They follow step-by-step. When I get the second response I parse it and save 20 URLs in format http://lalala-xx.jpg. After that I want to load images and put them into UICollectionView, and I want to do it not all in scope but in scheme "downloaded->straight to cell". I save URLs and images in singleton class and get access to them just like

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    cell.imageView.image = [[UserData sharedUser].images objectAtIndex:indexPath.row];
    return cell;
}

The chain of methos looks like

- (void)method1
{
    NSString     *string  = [NSString stringWithFormat:firstRequestString];
    NSURL        *url     = [NSURL URLWithString:string];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.responseSerializer = [AFJSONResponseSerializer serializer];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
     {
         // getting needed part for second request
         [self method2:(NSString *)part1];
     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
         // show error
     }];

    [operation start];
}

Second method:

- (void)method2:(NSString *)part1
{
    // lalala making secondRequestString
    NSString     *string  = [NSString stringWithFormat:secondRequestString];
    NSURL        *url     = [NSURL URLWithString:string];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.responseSerializer = [AFJSONResponseSerializer serializer];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
     {
         NSMutableArray *imageURLs = [[NSMutableArray alloc] init];
         // getting needed URLs 
         [self loadAllImages:(NSMutableArray *)imageURLs];
     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
         // show error
     }];

    [operation start];
}

Last:

- (void)loadAllImages:(NSMutableArray *)imageURLs
{
    // ???
}

I'm stuck. What should I do next? I have 20 URLs, but how should I download images and direct them to ViewController to update image in cells? I suppouse AFNetworkig can provide me some operation queue.
And I dont like my code now. I use this chain, but I want an independent method2 returning imgURLs. So it should look: User presses button -> method1 -> method2 -> stop. Wait untill user presses button -> download image1 -> show image1 -> download image2 -> show image2 -> and so on -> download imageN -> show imageN -> stop. I'll repeat, I need to store images in Array, I'll use it after that. Thx u read that.

///////////////////////////////////// UPDATE /////////////////////////////////////

I found solution. But it does not satisfy me completely. Images come randomly. How to make them load in order?

- (void)loadAllImages:(NSMutableArray *)imageURLs
{        
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    for (NSURL *url in imageURLs)
    {
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
        operation.responseSerializer = [AFImageResponseSerializer serializer];

        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
         {
             [[UserData sharedUser].images addObject:responseObject];
             [[NSNotificationCenter defaultCenter] postNotificationName:@"CollectionViewRealoadData" object:nil];
         }
         failure:^(AFHTTPRequestOperation *operation, NSError *error)
         {
             // show error
         }];

        [manager.operationQueue addOperation:operation];
    }
}
1

There are 1 best solutions below

2
On

You need to get the data from the URLs and then create a UIImage object from that data.

You can get the data from the URL using the NSURL methods

 for(NSString *imgString in imageURLs){
     NSURL *url = [NSURL URLWithString:imgString];
     NSData *imgData = [NSData dataWithContentsOfURL:url];
     UIImage *img = [UIImage imageWithData:imgData ];

     [imageUrls addObject:img];//this mutable array should be initialized early in view controller life cycle (like ViewDidLoad). 
  }

Once you have your image object you can add it to your array of images that you are using as a datasource for your collection view.

   [_collectionView insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:[imageUrls count] - 1 inSection:0]]];

//reload your collection view once you add new data