I am using the google places api to get details about stores near the user. The response I get from the call, I display in a table view. I make two api calls. One call to find nearby stores, and another call to get information about each returned store such as url, phone number, picture etc. So I first made both these calls on the main thread and it slowed down my UI. The table view lagged a lot while scrolling (but all the cells had correct data and when scrolling up or down the data did not change). Then I decided to use nsurlsessiontask to perform both the api calls so it would not slow down the UI. Here is code:
First api call:
s1 = @"Http request";
NSURL *jsonURL = [NSURL URLWithString:[self urlEncodeValue:s1]];
NSString *jsonDataString = [[NSString alloc]initWithContentsOfURL:jsonURL];
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:jsonURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (data == nil || error != nil) {
NSLog(@"error: %@", error);
return;
}
NSError *parseError;
self.jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (self.jsonDict)
{
//perform taks
}
So basically I created and initialized the jsonDict which the the dictionary that holds the data. Now in my class that shows the tableview, I take the data from jsonDict and display it in the cell. For example:
cell.addresslabel = [[[appDelegate.jsonDict objectForKey@"results"] objectAtIndex:indexPath.row] objectForKey:@"address"];
In order to get the phone number and website of the store I need to make another http request. So I make a a method in the same class that displays the tableView. Here is the code:
s2 = @"Second http request"
NSURL *jsonURL = [NSURL URLWithString:s2];
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:jsonURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (data == nil || error != nil) {
NSLog(@"error: %@", error);
return;
}
NSError *parseError;
phoneDic = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (phoneDic) {
//perform tasks
} else {
NSLog(@"parseError: %@", parseError);
NSLog(@"responseString: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}
}];
[task resume];
So when I do this the table view does not "lag" however the data shown is incorrect(cells show data of other cells) and when I scroll up or down the data changes? So when I perform task on main thread there is lag but correct data is displayed, when I use nsurlsessiontask there is no lag but the data shown is incorrect. I am doing anything wrong with the nsurlsessiontask?
The reason for your problem is that once the NSURLSessionTask has completed, the cell might be reused at a totally different position. Once you dequeue a cell in cellForRowAtIndexPath, you could stop a previously running task and restart a new one. Ideally the data requesting task is done separately from the presentation in the UITableView, including caching of received data.