Question

I am performing a simple get request with Apple's NSURLSession#dataTaskWithURL method

[[mySession dataTaskWithURL:myUrl completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
   // fancy code goes here...
 }] resume];

If I want to have a condition to do something IF the status code was a success, it appears that I have to cast the NSURLResponse as a NSHTTPURLResponse.....

    NSUInteger statusCode = ((NSHTTPURLResponse *)response).statusCode;
    if (!error && statusCode == 200) {
      // even fancier code goes here
    } else {
      // omg!!!!!!!!!
    }

...

But---------- My question is: WHY!?!?!?!?!?!?!?

Why in the world would Apple pass in a response object casted to a type that doesn't know its own status?! The fact that I had to write this code makes me think I am doing something very wrong, and there has to be a better way to know whether it was a 200, 404, or 500...

I was hoping I could just change the completionHandler's block argument types to be a NSHTTPURLResponse, however that appears to be a no go!

Was it helpful?

Solution

Protocol design, if done well, always has an eye on the future.

Though we're only using NSURLSession for HTTP right now, it might be possible in the future to use it for other networking protocols. It wouldn't surprise me if you could use it for FTP at some point, for example.

Using a simple response base class for the completion block/delegate parameter and letting you cast based on what kind of network protocol you know you're using gives NSURLSession flexibility for the future.

If a new networking protocol emerges with different needs—perhaps it doesn't even have an integer status code in its response, say—Apple can just add another subclass of NSURLResponse, and leave everything else the same, including the signature of the completion handler block and all the NSURLSession*Delegate protocols.

If they'd "hard coded" the network protocols and completion handler blocks to use NSHTTPURLResponse, then how would you cleanly add a new network protocol, say FTP, to NSURLSession?

(NB: By "protocol", as opposed to "networking protocol"—I use both terms in this answer—I mean the design of the interfaces of the NSURLSession classes, including their actual protocols and equivalent completion handlers.)

OTHER TIPS

Typecast an instance of NSHTTPURLResponse from the response and use its statusCode method.

[NSURLConnection sendAsynchronousRequest:myRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
    NSLog(@"response status code: %ld", (long)[httpResponse statusCode]);
    // do stuff
}];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top