AndrewSB AndrewSB - 5 months ago 46
iOS Question

NSURLSession delegate vs. completionHandler

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?

Answer

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 the 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
Comments