简体   繁体   中英

Asynchronous JSON request

I have a table view that works fluidly until I add a URL request to the code.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

...
   //Get Total Comments
    NSString *strURL = [NSString stringWithFormat:@"http://XX.XX.XX.XX/php/commentsTotal.php?CID=%@", [dict objectForKey:@"id"]];
    NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];


// to receive the returend value
NSString *strResultCI = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
cell.commentCount.text = strResultCI;


return cell;

}

The issue is that as you scroll through the table cells, the phone has to communicate back to my server, wait for the response and then display it to the cell.
Needless to say it has crippled my table performance. My question is: Does anyone have a good example or tutorial on how to simply add a JSON data request to a background thread? I am using SDWebImage to asynchronously handle the images, but don't know where to begin with the data portion.

I think what you need to do is:

  1. make a simple cache like an array of dictionaries, where key is url and value is data .

  2. when you show a new cell check the cache at first , if nothing is in there - send asynchronous request to the server (also it is good to know if we are waiting for the response)

  3. when you receive a response from the server fill the cache and check the tableView visible cells , if you received a data for a visible cell do it using tableView updates (not reload data, because it would be slow)

as for me, i am using AFNetworking library for API calls (also ASIHTTPRequest was good)

by the way, i think you should cancel requests when user scrolls fast, that could be done through NSOperationQueue . You probably don't want all of those requests be running at the same time, it is better to have only those active, which data you need most and cancel others

If this is the only point at which you will do server/client communication, you simply need to do an asynchronous NSURLConnection.

Else if you are doing a lot of client/server communication the best approach would be AFNetworking or any other http client library.

when ever you need to retrieve JSON data back from a webserver and need to do it in a background thread try doing:

dispatch_queue_t webCall = dispatch_queue_create("web call", NULL);
dispatch_async(webCall, ^{
NSString *strURL = [NSString    stringWithFormat:@"http://XX.XX.XX.XX/php/commentsTotal.php?CID=%@", [dict objectForKey:@"id"]];
NSData *dataURL = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]]];
});
dispatch_async(dispatch_get_main_queue(), ^{
NSString *strResultCI = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding]; cell.commentCount.text = strResultCI;
});

use NSJSONSereliazation class in foundation to parse the json data. it returns either dictionary or a array depending on the data. dispatch_async(webCall, ^...); creates a background thread for you and dispatch_async(dispatch_get_main_queue(), ^... get the main thread back, this is needed for when you need to do anything UI related like change the cells texts.

Also note, try to have your table view cells data ready before hand and not in -tableView: cellForIndexPath .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM