3

I'm getting JSON data from the web, parse it, then using it to diplay pins on a map.

Here is method one, which there is no problem with:

NSString *CLIENT_ID = @"SECRET_ID";
    NSString *CLIENT_SECRET = @"CLIENT_SECRET";

    NSString *SEARCH = [NSString stringWithFormat:@"https://api.foursquare.com/v2/venues/search?near=gjovik&query=cafe&client_id=%@&client_secret=%@&v=20140119", CLIENT_ID, CLIENT_SECRET];

    NSURL *searchResults = [NSURL URLWithString:SEARCH];
    NSData *jsonData = [NSData dataWithContentsOfURL:searchResults];

    NSError *error = nil;
    NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];

    self.venues = dataDictionary[@"response"][@"venues"];

    [self loadAnnotationsAndCenter:YES];

[self loadAnnotationsAndCenter:YES]; retrieves the lat and lng from the JSON file and uses it to display pins on the map.

I decided to change my code uing NSURLSession. Here's what it looks like:

NSString *CLIENT_ID = @"SECRET_ID";
NSString *CLIENT_SECRET = @"CLIENT_SECRET";

NSString *SEARCH = [NSString stringWithFormat:@"https://api.foursquare.com/v2/venues/search?near=gjovik&query=cafe&client_id=%@&client_secret=%@&v=20140119", CLIENT_ID, CLIENT_SECRET];

NSURL *URL = [NSURL URLWithString:SEARCH];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        self.venues = dataDictionary[@"response"][@"venues"];
        [self loadAnnotationsAndCenter:YES];
    }];

    [task resume]

NSURLSession is between 10 and 30 seconds slower than the first method. I don't understand why that is. The search string, in this case, returns 27 different locations, if that matters

Cheers.

Nilzone-
  • 2,766
  • 6
  • 35
  • 71

2 Answers2

11

You need to ensure that UIKit methods will be executed on the main thread.

The block of the completion handler will be executed on the "delegate queue" (see delegateQueue property of NSURLSession).

You can accomplish this in two ways: either setup the delegate queue which is the main queue ([NSOperationQueue mainQueue]) or use

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self loadAnnotationsAndCenter:YES]; 
});

in your completion block.

Luigi
  • 4,129
  • 6
  • 37
  • 57
CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67
  • Thanks! This maybe is a silly question, but I'm new to IOS. How can I know my function is a/part of a UIKit method? – Nilzone- Jan 22 '14 at 12:59
  • @Nilzone- If you update the UI, i.e. is it one of these classes: https://developer.apple.com/library/ios/documentation/uikit/reference/UIKit_Framework/_index.html – Rob Jan 22 '14 at 13:09
0

In Swift:

dispatch_async(dispatch_get_main_queue()) {
}
Kaptain
  • 1,358
  • 12
  • 20
  • Some explanation with the code might help in understanding the issue and why your code would solve the problem – dvhh Sep 10 '15 at 01:47