5

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!

4

2 回答 2

7

协议设计,如果做得好,总是着眼于未来。

虽然我们现在只将 NSURLSession 用于 HTTP,但将来可能会将其用于其他网络协议。例如,如果您可以在某些时候将它用于 FTP,我不会感到惊讶。

为完成块/委托参数使用一个简单的响应基类,并让你根据你知道你正在使用的网络协议类型进行转换,这为 NSURLSession 未来提供了灵活性。

如果一个新的网络协议出现了不同的需求——也许它的响应中甚至没有整数状态码,比如说——Apple 可以添加另一个 NSURLResponse 子类,而其他一切都保持不变,包括完成处理程序的签名块和所有NSURLSession*Delegate协议。

如果他们“硬编码”了要使用的网络协议和完成处理程序块NSHTTPURLResponse,那么你将如何干净利落地添加一个新的网络协议,比如 FTP,到 NSURLSession?

(注意:“协议”,而不是“网络协议”——我在这个答案中使用了这两个术语——我的意思是 NSURLSession 类的接口的设计,包括它们的实际协议和等效的完成处理程序。)

于 2014-04-18T07:02:35.167 回答
0

对来自响应的实例进行类型转换NSHTTPURLResponse并使用其statusCode方法。

[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
}];
于 2015-09-12T11:31:28.303 回答