Navjot Singh Navjot Singh - 1 year ago 84
iOS Question

How to load images from API/URL asynchronously?

I am fetching images synchronously from an array which stores URLs of images but it work very slowly. Now i want to load them asynchronously for fast working.

Heres the code and provide answer with coding.

#import "DetailViewController.h"
#import "FinalViewController.h"

@interface DetailViewController ()


@implementation DetailViewController
@synthesize jsonData;

- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Select a Photo";

// Do any additional setup after loading the view.
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

NSURL *url = [NSURL URLWithString:@""];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(nonnull NSURLResponse *)response
data1 = [[NSMutableData alloc] init];

-(void)connection:(NSURLConnection *)connection didReceiveData:(nonnull NSData *)theData
[data1 appendData:theData];

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

jsonArray1 = [NSJSONSerialization JSONObjectWithData:data1 options:nil error:nil];
[mainTableView reloadData];


-(void)connection:(NSURLConnection *)connection didFailWithError:(nonnull NSError *)error
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Please make sure you are connected to either 3G or Wi-Fi." delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil, nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.

- (int)numberOfSectionInTableView:(UITableView *)tableView
return 1;

- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [jsonArray1 count];

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];

cell.textLabel.text = [[jsonArray1 objectAtIndex:indexPath.row] objectForKey:@"title"];
cell.detailTextLabel.text = [NSString stringWithFormat:@"URL : %@", [[jsonArray1 objectAtIndex:indexPath.row] objectForKey:@"url"]];

NSURL *URL = [[NSURL alloc] initWithString:[[jsonArray1 objectAtIndex:indexPath.row] valueForKey:@"thumbnailUrl"]];

NSData *URLData = [[NSData alloc] initWithContentsOfURL:URL];
[[cell imageView]setImage:[UIImage imageWithData:URLData]];

return cell;

-(void)tableView:(UITableView *)tableview didSelectRowAtIndexPath:(NSIndexPath *)indexPath
FinalViewController *fvc = [[FinalViewController alloc] initWithNibName:@"FinalViewController" bundle:nil];
fvc.jsonData2 = [jsonArray1 objectAtIndex:indexPath.row];
[self.navigationController pushViewController:fvc animated:YES];



Answer Source

You can do like this:

cell.tag = indexPath.row;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {

    NSData *imageData = [NSData dataWithContentsOfURL: URL];

    UIImage* image = [[UIImage alloc] initWithData:imageData];
    if (image) {
         dispatch_async(dispatch_get_main_queue(), ^{
             if (cell.tag == indexPath.row) {
                 cell.imageView.image = image;
                 [cell setNeedsLayout];

Ref: Asynchronous downloading of images for UITableView with GCD

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download