Im following tutorial and i typed method like follow:
+(void)downlaodDataFromURL:(NSURL *)url withCompletionHandler:(void (^)(NSData *))completionHandler{
// Instantiate a session configuration object
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// Instantiate a session object
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
// Create a data task object to perform the data downloading
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error != nil){
// If any error occurs then just display its description on the console
NSLog(@" %@", [error localizedDescription]);
}
else {
//If no errors occurs, check the HTTP status code.
NSInteger HTTPStatusCode = [(NSHTTPURLResponse*)response statusCode];
//If it's other than 200, then show it on console.
if (HTTPStatusCode != 200){
NSLog(@"HTTP status code = %d", HTTPStatusCode);
}
//Call the completion handler with the returned data on the main thread.
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completionHandler (data);
completionHandler (data);
}];
}
}];
//Resume the task
[task resume];
}
I have 2 question:
First - in method declaration i've seen following: withCompletionHandler:(void (^)(NSData *))completionHandler. I have never seen construction like (void (^). In my understanding of method syntax, we have arguments and type, that method should return or not, but what is that? I've never seen voidin place like this, and what is (^)? I know, ^ means block, but what about that construction?
Second - in
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completionHandler (data);
}];
I see completionHandler (data);. There is round brackets, completionHandler is declared in top method, and data is obvious the data, we got from the URL. But what exactly that does and what is - completionHandler? When i look at (void (^)(NSData *))completionHandler i think that completionHandler is object of NSData type. That make no sense for me. I guess, i just can't understand syntax correctly.
Could u please provide an explanation? I know the whole meaning of this, but this 2 chunks of code confuse me.. Thank you!
EDIT:
In my viewController.m i have a method declared as follow:
-(void)getCountryInfo{
//Prepare the URL that we'll get the country info data from.
NSString *URLString = [NSString stringWithFormat:@"http://api.geonames.org/countryInfoJSON?username=Necrosoft&country=%@", self.countryCode];
NSURL *url = [NSURL URLWithString:URLString];
[AppDelegate downlaodDataFromURL:url withCompletionHandler:^(NSData *data){
//Check if any data returned
if (data != nil){
//Convert the returned data into a dictionary
NSError *error;
NSMutableDictionary *returnedDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (error != nil){
NSLog(@"%@", [error localizedDescription]);
}
else {
self.countryDetailsDictionary = [[returnedDict objectForKey:@"geonames"] objectAtIndex:0];
NSLog(@"%@", self.countryDetailsDictionary);
//Set the country name to the respective label.
self.lblCountry.text = [NSString stringWithFormat:@" %@ (%@)", [self.countryDetailsDictionary objectForKey:@"countryName"], [self.countryDetailsDictionary objectForKey:@"countryCode"]];
//Reload the table view.
[self.tblCountryDetails reloadData];
//Show the table view.
self.tblCountryDetails.hidden = NO;
}
}
}];
}
There is a class method call that was described above:
[AppDelegate downlaodDataFromURL:url withCompletionHandler:^(NSData *data){
...// there is code pasted above
So, if i understand correct, completionHandler (data); invokation defined as follow:
//Check if any data returned
if (data != nil){
//Convert the returned data into a dictionary
NSError *error;
NSMutableDictionary *returnedDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (error != nil){
NSLog(@"%@", [error localizedDescription]);
}
else {
self.countryDetailsDictionary = [[returnedDict objectForKey:@"geonames"] objectAtIndex:0];
NSLog(@"%@", self.countryDetailsDictionary);
//Set the country name to the respective label.
self.lblCountry.text = [NSString stringWithFormat:@" %@ (%@)", [self.countryDetailsDictionary objectForKey:@"countryName"], [self.countryDetailsDictionary objectForKey:@"countryCode"]];
//Reload the table view.
[self.tblCountryDetails reloadData];
//Show the table view.
self.tblCountryDetails.hidden = NO;
When data is an NSData object which we successfully download with :
AppDelegate downlaodDataFromURL:url withCompletionHandler:^(NSData *data)
Am i right?