我正在使用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,但这似乎是不行的!
答案 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
}];