1

This may be a very silly question!! But, as I am having a doubt, thought of asking here.

  1. Are the two delegate methods (i.e. connection:didReceiveResponse: and connection:didFailWithError:) are mutually exclusive to each other? I mean is there any scenario in which both the delegate methods could get called by NSURLConnection object?

  2. In case only connection:didFailWithError: gets called, how to retrieve the HTTP status code?

Fabio Cardoso
  • 1,181
  • 1
  • 14
  • 37
Rashmi Ranjan mallick
  • 6,390
  • 8
  • 42
  • 59

1 Answers1

2

From the docs:

The only case where this message is not sent to the delegate is when the protocol implementation encounters an error before a response could be created.

NSURLConnectionDelegate Class Reference

So, a NSURLConnection could fail before it gets a response, however it could fail after. Since connection:didFailWithError ceases any further messages for that connection, the following two scenarios could happen:

  1. The connection is started, fails to get a response and connection:didFailWithError is called.
  2. The connection is started and gets a response, connection:didReceiveResponse: is called, then the connection fails for some reason (The network connection could drop out for example), before connectionDidFinishLoading is called.

You will need to get the HTTP status code from connection:didReceiveResponse, if that method isn't called, there is no status code as it is part of the response. If you need to access it from within connection:didFailWithError you will need to record it.

Note that to get the status code, you will also need to case NSURLResponse to NSHTTPURLResponse like so:

NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"Status code %ld", httpResponse.statusCode);
Ben Kelly
  • 253
  • 2
  • 10
  • So, when connection: didReceiveResponse: is called, it can either end up in connection: didFinishLoading: or connection: didFailWithError: ? – Rashmi Ranjan mallick Aug 14 '15 at 13:53
  • If it's successful, it'll call didReceiveData: where you need to record the data (easiest way is to used appendData on an NSMutableData object) before calling didFinishLoading: if it's successful. If it fails it may still call didReceiveData before failing (as the connection could fail at any point). But yes, the connection should either end up calling either connection:didFinishLoading or connection:didFailWithError: – Ben Kelly Aug 14 '15 at 14:00
  • Sorry for late reply!! How to capture network errors like 400, 404, 500 etc. Do they get notified in connection: didReceiveResponse: or connection: didFailWithError: ? – Rashmi Ranjan mallick Aug 16 '15 at 21:23
  • Basically, I want to know how to handle all kinds of error scenarios without missing something. Can I get all the errors in connection: didFailWithError: or I need to depend on connection: didReceiveResponse: also? This will be helpful!! – Rashmi Ranjan mallick Aug 16 '15 at 21:25
  • They get notified in connection:didRecieveResponse. Those errors are status codes from the server and form part of the servers response. – Ben Kelly Aug 16 '15 at 21:26
  • Ok thanks. I am getting into it slowly. So, in case of those errors ( 400, 404, 500 etc), first connection: didReceiveResponse: will be called as you said. After that, which method will be called. It's connection: didFinishLoading: or connection: didFailWithError: ? – Rashmi Ranjan mallick Aug 16 '15 at 21:32
  • IIRC, you'll get didFinishLoading unless the connection is terminated early (e.g. by a network failure). A server's response code indicates a server-side error, whereas didFailWithError typically indicates a communication error or library error. Each of those error responses also contains a body (often just the word "forbidden", but it could just as easily be a full web page with explanatory text). So when you get one of those error codes, the request really does complete successfully; it just doesn't provide you with the data you were expecting. – dgatwood Sep 15 '15 at 06:43
  • As a rule, if you care about the error page body, go ahead and let the request continue to fetch data. Otherwise, you should cancel the request in your didReceiveResponse: method. If you do so, you won't get any more callbacks for that request. – dgatwood Sep 15 '15 at 06:44