SteBra
SteBra

Reputation: 4247

How to reload tableView after async fetching JSON ? Objective C

This is my code for async fetching JSON

-(void)viewDidAppear:(BOOL)animated
{
 [_indicator startAnimating];
_indicator.hidesWhenStopped = YES;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    //Load the json on another thread

    [Constants shared].jsonData = [[NSData alloc] initWithContentsOfURL:
                                   [NSURL URLWithString:@"http://api.fessor.da.kristoffer.office/homework/index/?rp[token]=app&rp[workspace]=parent&child_id=22066&type=parent&start_date=2014-05-01&end_date=2014-05-01"]];

    //When json is loaded stop the indicator
    [_indicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES];

    [self declareVariables];
    [_tableView reloadData];

});
}

And it's not working for some reason. It shows the spinner, I can see that the data is fetched, it stops and hides the spinner, but the tableView is not reloaded, it's blank.

Upvotes: 1

Views: 5552

Answers (2)

Mark S.
Mark S.

Reputation: 4017

You want to move all the UI stuff to the main queue. So your code should read as:

-(void)viewDidAppear:(BOOL)animated
{
    [_indicator startAnimating];
    _indicator.hidesWhenStopped = YES;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
    //Load the json on another thread

    [Constants shared].jsonData = [[NSData alloc] initWithContentsOfURL:
                                   [NSURL URLWithString:@"http://api.fessor.da.kristoffer.office/homework/index/?rp[token]=app&rp[workspace]=parent&child_id=22066&type=parent&start_date=2014-05-01&end_date=2014-05-01"]];
    dispatch_async(dispatch_get_main_queue(), ^{
       //When json is loaded stop the indicator
       [_indicator stopAnimating];
       [self declareVariables];
       [_tableView reloadData];
       });
    });
}

This way your JSON is loaded on the background queue and the UI is updated on the main queue.

Upvotes: 5

sweepy_
sweepy_

Reputation: 1331

You should try to reload your table view on the main thread. Use GCD to dispatch on the main thread.

dispatch_async(dispatch_get_main_queue(), ^{
    [_tableView reloadData];
});

If there's no result, try to log in the cellForRowAtIndexPath method to check whether the reload is done or not. If so, you error is elsewhere.

Upvotes: 2

Related Questions