Use NSURLSessionDelegate or NSURLSessionDataTask

Hello everyone.

I was wondering if it is recommended to use NSURLSessionDelegate (NSURLSessionDataDelegate, NSURLSessionTaskDelegate) in your class and how or to use simply the NSURLSessionDataTask.


Using NSURLSessionDelegate :

//In header file
interface ViewController : UIViewController <NSURLSessionDataDelegate, NSURLSessionTaskDelegate>
//In .m file implement the following:
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler


or

   
NSURLSessionDataTask* task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
       
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            NSLog(@"%@", json);
       
     }];
     [task resume];


The authorization is used, it is BASIC.

    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.testwebpage.com"]];
     //Get values from textfiedds
    NSURLCredential *newCredential = [NSURLCredential credentialWithUser:self.txtfield_username.text
                                                                    password:self.txtfield_password.text
                                                                 persistence:NSURLCredentialPersistenceNone];

    NSString *authStr = [newCredential user];
    authStr = [authStr stringByAppendingString:@":"];
    authStr  = [authStr stringByAppendingString:[newCredential password] ];
       
    NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];

    NSString *authValue = [NSString stringWithFormat: @"Basic %@",[authData base64EncodedStringWithOptions:0]];
    [request setValue:authValue forHTTPHeaderField:@"Authorization"];


Regards,

kalgik

Replies

I found that having access to the delegate method:

URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:

was very important for websites that wanted to interact with certain web browsers.

I would like clarify my question.


I was wondering which of two possible options would be the better one in the aspects of performance and robustness.

1)The "block" way of NSURLSession:

//e.g.
NSURLSessionDataTask* task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    
      NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
      NSLog(@"%@", json);
}];
[task resume];


2) or the "delegate" way of NSURLSession:

NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate: self delegateQueue: [NSOperationQueue mainQueue]];

using its delegate methods

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

and

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error

amd

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


Is any difference or is just a different way of writing expression?


Regards,

kalgik

Either approach is fine. There are some circumstances where the ‘block’ approach won’t work, for example:

  • When using a background session

  • When dealing with very large data responses

  • When dealing with a streamed response

There are also some circumstances where you need a delegate even though you’re using the convenience API for most of your work (for example, handling authentication challenges). That’s fine btw, you can mix’n’match.

If none of these specific requirements apply then it’s really up to your personal preference.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

WWDC runs Mon, 5 Jun through to Fri, 9 Jun. During that time all of DTS will be at the conference, helping folks out face-to-face. http://developer.apple.com/wwdc/

Dear eskimo,


I noticed that when there are "very large data responses", the 'block' approach is the most working one. The large data response is collected without missing any of them(characters). Besides, this approach blocks the program execution until it receives the data.


On the other hand, if I use the "delegate" approach for large data response, the reponse will come partially and unfinished (some characters will be missed). Thus, I can not continue parsing the repsonse successfully (e.g. json data respone).


So, I do not recommend the "delegate" method for large data response.


Ragards,

kalgik

So, I do not recommend the "delegate" method for large data response.

I strongly suspect that there’s something wrong with your code or your test methodology here. Internally the convenience APIs are implemented in terms of the delegate APIs, so it’s hard to imagine any scenario where the convenience APIs work work while the delegate APIs fail.

On the other hand, if I use the "delegate" approach for large data response, the reponse will come partially and unfinished (some characters will be missed).

I’ve seen folks have trouble like this before and the most common cause is a failure to accumulate the chunks of data you get back from the multiple

-URLSession:dataTask:didReceiveData:
delegate callbacks correctly.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"