Как получить код состояния из NSURLResponse dataTaskWithURL?

Я выполняю простой запрос на получение с помощью метода Apple NSURLSession # dataTaskWithURL

[[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 ...

Я надеялся, что смогу просто изменить типы аргументов блока завершенияHandler на NSHTTPURLResponse, но это оказалось бесполезным!


person patrick    schedule 17.04.2014    source источник


Ответы (2)


Дизайн протокола, если он сделан хорошо, всегда смотрит в будущее.

Хотя сейчас мы используем только NSURLSession для HTTP, возможно, в будущем его можно будет использовать для других сетевых протоколов. Меня не удивило бы, если бы вы могли использовать его, например, для FTP.

Использование простого базового класса ответа для параметра блока завершения / делегата и возможность приведения в соответствие с тем, какой тип сетевого протокола вы используете, дает NSURLSession гибкость в будущем.

Если появляется новый сетевой протокол с другими потребностями - возможно, он даже не имеет целочисленного кода состояния в своем ответе, - Apple может просто добавить еще один подкласс NSURLResponse и оставить все остальное без изменений, включая подпись блока обработчика завершения и всех NSURLSession*Delegate протоколов.

Если бы они «жестко запрограммировали» сетевые протоколы и блоки обработчика завершения для использования NSHTTPURLResponse, то как бы вы добавили новый сетевой протокол, скажем, FTP, в NSURLSession?

(NB: Под «протоколом», а не «сетевым протоколом» - я использую оба термина в этом ответе - я имею в виду дизайн интерфейсов классов NSURLSession, включая их фактический протоколы и эквивалентные обработчики завершения.)

person Matt Gibson    schedule 18.04.2014

Приведите экземпляр 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
}];
person Nishant    schedule 12.09.2015
comment
лол вау, не могу поверить, что ты копируешь и вставляешь еще один ответ вот так ... stackoverflow.com/a/25431043/1474817 - person emotality; 03.04.2017
comment
@emotality: SO - это платформа для обмена. Существование этого вопроса показывает, что другого ответа было недостаточно. Я принес его сюда. Теперь, когда вы это увидели, вам лучше "поверить". - person Nishant; 05.04.2017
comment
лол продолжай говорить себе это. Дайте свои собственные ответы ... обычно копируйте и вставляйте. - person emotality; 05.04.2017