0

I have UICollectionViewCell with dynamic content download (image download). I have download in block in cell:

-(MainVCCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"MainVCCell";

    MainVCCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    Person *person = [self.fetchedResult objectAtIndex:indexPath.row];

    [cell.login setText:person.login];

    if(person.avatar) {
        [cell.avatarImageView setImage:[UIImage imageWithData:person.avatar]];
    } else {
        [cell.avatarImageView setImage:[UIImage imageNamed:@"placeholder"]];
        [AsyncUrl request:[NSString stringWithFormat:@"some SSL URL",person.login] completeBlock:^(NSData *data) {
            dispatch_queue_t downloadQueue = dispatch_queue_create("Download queue", NULL);
            dispatch_async(downloadQueue, ^{
                dispatch_async(dispatch_get_main_queue(), ^{
                    MainVCCell *cellToUpdate = (MainVCCell*)[collectionView cellForItemAtIndexPath:indexPath];
                    if(cellToUpdate) {
                        [cellToUpdate.avatarImageView setImage:[UIImage imageWithData:data]];
                    }
                    person.avatar = data;
                    [[CoreDataController sharedInstance] saveContext];
                });
            });
        } errorBlock:^(NSError *error) {
            NSLog(@"%@",error);
        }];

    }

    return cell;
}

And it work fine, but of course when i scroll several times, i get so many connections and download fire that some of them even timeout. I understand why is this happening. Is there a way to cancel connections in invisible cell blocks? I want to download only a visible content.

I'm familiar with SDWebImage but this library is not support SSL connections, so i can't use it.

Jakub
  • 13,712
  • 17
  • 82
  • 139
  • Do you mean that the certificate is invalid and you need to work around that? But that you don't want to edit SDWebImage code? – Wain Jan 29 '14 at 13:47
  • I don't want to use it 3-party for it because SDWebImage solved one problem and creating much bigger one. – Jakub Jan 29 '14 at 13:52

3 Answers3

0

Collection views have a delegate method that is called when the cell disappears

- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath

Just make sure you have a method for stop the connection, then call that method.

UICollectionViewDelegate Protocol

A'sa Dickens
  • 2,045
  • 1
  • 16
  • 21
  • I am more accustomed to the NSURLConnection rather than the GDC, so i can't really provide example code. – A'sa Dickens Jan 29 '14 at 13:44
  • Thanks, but how can I use delegate to download image to cells? Where to set a delegate for it? – Jakub Jan 29 '14 at 14:09
  • Under cell for item at index path method, you call a method in the cell for [download Image] which does all the download actions – A'sa Dickens Jan 29 '14 at 14:44
  • So the download should be in the cell subclass? And to it attach the delegate. This is serious MVC violation – Jakub Jan 29 '14 at 15:31
0

I strong recommend you to use AFNetworking.

Then you create an array of NSOperation in your viewDidLoad:

self.operationQueue = [[NSMultableArray alloc]init];

In your -(MainVCCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath, make something similar to this:

AFHTTPRequestOperation *operation [[AFHTTPRequestOperation alloc] initWithRequest:posterURLRequest];      
operation.responseSerializer = [AFImageResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) 
    {
        if(cellToUpdate) {
          [cellToUpdate.avatarImageView setImage:[UIImage imageWithData:data]];
        }
        person.avatar = data;
        [[CoreDataController sharedInstance] saveContext];             
    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error)
    {
      // manage errors
    }];
    [self.operationQueue addObject:operation];
    [operation start];

Them At - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath

[self.operationQueue[indexPath.row] cancel];
Guilherme Torres Castro
  • 15,135
  • 7
  • 59
  • 96
-2

use NSURLConnection to start a download.

Create a subClass of NSObject which has one NSUrlConnection instance property , for this subclass you provide a link and it will download the image using NSUrlConnection.
Create instances of this class when ever you want to download an image and push it into an array ( say ConnectionsArray).

When you think, you dont want to download particular indexPaths images, just cancel those by using ConnectionsArray.
Get that particular download-instance using indexPath and ConnectionsArray,and call cancel method of NSURLConnection of that object.

NSURLConnection has cancel method, which cancels the ongoing operation.

santhu
  • 4,796
  • 1
  • 21
  • 29