0

I am initialising up an NSURLConnection with a request and have both didFailWithError and didReceiveData setup.

The application will successfully use both these methods for any situations wear I want it to use them but if you switch to offline mode whilst in the app, didFailWithError get called for any delegate I have set up even though I no longer need them.

If a real user lost their connection I don't want these methods to execute.

-(void) RequestExample 
{
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:someRequest delegate:self];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    [self NotifyObserversOfFailure];
}

-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    [self NotifyObserversOfSuccess];
}

Someone suggested checking the error code in these methods but that doesn't feel like a fix. Somewhere else I have read is to nil the connection but where would I put this because putting it in the didReceiveData method doesn't work.

Thanks for your help

Kurtis
  • 1,172
  • 2
  • 12
  • 20

2 Answers2

0

I think you are misunderstanding the nature of connection:didReceiveData:. If all of the data does not fit within one packet, this method will be called multiple times.

From Apple's docs:

Sent as a connection loads data incrementally. This method provides the only way for an asynchronous delegate to retrieve the loaded data. It is the responsibility of the delegate to retain or copy this data as it is delivered.

Typically, you would hold a NSMutableData ivar and call [_mutableData appendData:data] each time connection:didReceiveData: is called.

EDIT:

I've noticed in my own apps that connection:didFailWithError: is called whenever the web service finishes, regardless of whether or not there is an error. So, you can use connection:didReceiveData: and connection:didFailWithError: to aggregate data and then know that the web service is complete.

paulrehkugler
  • 3,241
  • 24
  • 45
  • `connection:didFailWithError:` should only be called when the connection failed. So, there is something strange happening. – CouchDeveloper Oct 08 '13 at 17:25
  • I am using this to authenticate so the response is small. The problem is is that my app could be open for hours but when switched to offline mode or if the phone lost 3g, didFailWithError gets called for all delegates I have. I want the delegate for login and to disable or to remove it if possible. Is there any way to do that or to stop it being called on connection failed? I could implement boolean logic but it feels like there'd be a better way. – Kurtis Oct 08 '13 at 21:08
  • The easiest way to handle this is nu appending the data continuo:-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [receivedData appendData:data]; } – Vincent Apr 09 '15 at 10:38
0

I worked this out eventually.

I was presuming that didFailWithError would be called if the phone lost 3G connection because I was simulating this by switching the phone into aeroplane mode. In doing this I was inactivating the app by opening the notification bar, and activating it when closing it, thus applicationDidBecomeActive was being call (which checked the session, failed and called didFailWithError).

I have now used didFinishLaunchingWithOptions.

I didn't know that didReceiveData would be called multiple times if the data was too large so thanks for your answer.

Sorry for the misleading question though.

Kurtis
  • 1,172
  • 2
  • 12
  • 20