NSURLSession delegate vs. completionHandler

29,667

If you want to add a custom delegate class, you need to implement the NSURLSessionDataDelegate and NSURLSessionTaskDelegate protocols at the minimum.

With the methods:

NSURLSessionDataDelegate - get continuous status of your request

 - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response
 completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {

    receivedData=nil; receivedData=[[NSMutableData alloc] init];
    [receivedData setLength:0];

    completionHandler(NSURLSessionResponseAllow);
}

NSURLSessionDataDelegate

-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
   didReceiveData:(NSData *)data {

    [receivedData appendData:data];
}

NSURLSessionTaskDelegate

 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error {
 if (error) {
  // Handle error
 }
else {
   NSDictionary* response=(NSDictionary*)[NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&tempError];
    // perform operations for the  NSDictionary response
}

If you want to separate the delegate code (middle layer) from your calling class (generally its good practice to have separate class/layer for network calls), the delegate of NSURLSession has to be :-

NSURLSession *session=[NSURLSession sessionWithConfiguration:sessionConfig delegate:myCustomDelegateClass delegateQueue:nil];

Ref Links:

  1. NSURLSession Class Reference
  2. iOS NSURLSession Example (HTTP GET, POST, Background Downlads )
  3. From NSURLConnection to NSURLSession
Share:
29,667

Related videos on Youtube

AndrewSB
Author by

AndrewSB

Updated on February 02, 2020

Comments

  • AndrewSB
    AndrewSB about 4 years

    I've always used completion handlers. With NSURLConnection and now with NSURLSession. It's led to my code being really untidy, especially I have request within request within request.

    I wanted to try using delegates in NSURLSession to implement something I've done untidily with NSURLConnection.

    So I created a NSURLSession, and created a dataTask:

    NSURLSessionDataTask *dataTask = [overallSession dataTaskWithURL:url
                                                      completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                          if(error == nil)
                                                          {
                                                              NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
                                                              NSLog(@"Data = %@",text);
                                                          }
    
                                                      }];
    
        [dataTask resume];
    

    Right now I have a completionHandler for the response, how would I switch to delegates to manage the response and data? And can I add another dataTask from the delegate of this one? Using the cookies that this dataTask created and placed into the session?

  • Smart Home
    Smart Home over 8 years
    If multiple concurrent requests can be in flight at the same time, this approach won't work since you will append data from different tasks together. In this case, use a dictionary to append only data belonging to particular task.
  • Lazar Kukolj
    Lazar Kukolj over 7 years
    thank you for the 2nd link! it helped a lot and was exactly what i needed!
  • dgatwood
    dgatwood over 7 years
    You can do all that stuff, but generally unless you're doing custom authentication, custom caching, or trying to make use of the data before you receive all of it (e.g. partial parsing of a web page to start rendering sooner), it is usually cleaner to use callbacks and hand off the resulting data to a method if things get too deeply nested and confusing. Just my $0.02.
  • Nikita
    Nikita about 6 years
    in case the delegate callbacks are configured to return on main queue, the [receivedData appendData:data]; can be an expensive operation, so it should be moved to global queue in an async way and there should be added a lock;