Search code examples
iosobjective-cuiimagensdatadispatch-async

Loading an image from web-service on to an UIImage doesn't work properly


I have got a productImageArray that contains url as elements of the array. I'm trying to load those urls in my image view.

Following is the way as of how I'm loading it.

UIActivityIndicatorView *spinner=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        spinner.center=CGPointMake(160.0,240.0 );
        spinner.hidesWhenStopped=YES;
        [self.view addSubview:spinner];
        [spinner startAnimating];

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
        dispatch_async(queue, ^{
             NSData *storeImageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:productImageArray[indexPath.row]]];
            self.productImage.image = [UIImage imageWithData:storeImageData];
            dispatch_sync(dispatch_get_main_queue(), ^{

                [spinner stopAnimating];
            });
        });

The problem is that,

  1. Only the last cell of my tableview loads the image whereas the remaining cell does not load the image from the url
  2. Is there any other better way of loading the image from url directly into my UIImage using native methods?

When I use the following code, each cell of my tableview loads the image data but still it freezes the User interface till the data is loaded completely

NSData *storeImageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:productImageArray[indexPath.row]]];

        self.productImage.image = [UIImage imageWithData:storeImageData];

Solution

  • try this

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
        dispatch_async(queue, ^{
             NSData *storeImageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:productImageArray[indexPath.row]]];
    
            dispatch_sync(dispatch_get_main_queue(), ^{
    
                [spinner stopAnimating];
                  self.productImage.image = [UIImage imageWithData:storeImageData];
            });
        });
    

    or try like

    self.productImage.image = nil;   //// [UIImage imageNamed:@"default.png"];
    
     NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:productImageArray[indexPath.row]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (data) {
            UIImage *currentImage = [UIImage imageWithData:data];
            if (currentImage) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    UITableviewCell *getCurrentCell = (id)[tableView cellForRowAtIndexPath:indexPath];
                    if (getCurrentCell)
                         self.productImage.image = currentImage;
                });
            }
        }
    }];
    [task resume];