如何从dataTaskWithURL NSURLResponse获取状态代码?

时间:2014-04-17 23:31:25

标签: objective-c nsurlsession nshttpurlresponse

我正在使用Apple的NSURLSession#dataTaskWithURL方法执行一个简单的get请求

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

如果我想有条件做某事,如果状态代码成功,似乎我必须将NSURLResponse转换为NSHTTPURLResponse .....

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

...

但是----------我的问题是:为什么!?!?!?!?!?!?!?

为什么Apple会将响应对象传递给一个不知道自己状态的类型?我必须编写这段代码的事实让我觉得我做的事情非常错误,必须有更好的方法来知道它是200,404还是500 ......

我希望我可以将completionHandler的块参数类型更改为NSHTTPURLResponse,但这似乎是不行的!

2 个答案:

答案 0 :(得分:7)

协议设计,如果做得好,总是关注未来。

虽然we're only using NSURLSession for HTTP right now,但将来有可能将其用于其他网络协议。例如,如果你可以在某些时候将它用于FTP,那就不会让我感到惊讶。

使用一个简单的响应基类作为完成块/委托参数,并根据您所知道的使用何种网络协议进行投射,为将来提供NSURLSession灵活性。

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

如果他们"硬编码"要使用NSHTTPURLResponse的网络协议和完成处理程序块,那么如何将新的网络协议(如FTP)干净地添加到NSURLSession?

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

答案 1 :(得分:0)

来自响应的Ty {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
}];