Search code examples
iphoneobjective-ciosnsurlconnectionnsrunloop

How to stop NSRunLoop


I have a background method that is called every 5 minutes.

That method use NSURLConnection to send data to web service.
In that method I have this code:

...
conn =  [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:NO];
    NSPort* port = [NSPort port];
    NSRunLoop* rl = [NSRunLoop currentRunLoop];
    [rl addPort:port forMode:NSDefaultRunLoopMode];
    [conn scheduleInRunLoop:rl forMode:NSDefaultRunLoopMode];
    [conn start];
    [rl run];
...

Because I call WS in background I use this code because without this delegate methods (didReceiveData, didFail... etc.) never get called.

I get this trick from http://www.cocoaintheshell.com/2011/04/nsurlconnection-synchronous-asynchronous/

The issue is when 5 minutes pass and this method is called for the first time it doesn't wait for next 5 minutes to call again but call web service almost every second.
I think that I should somehow invalidate this NSRunLoop but don't know how and where?


Solution

  • In case you were wondering why the delegate methods don't get called while your connection is in the background: If you put the connection in a background queue, it gets shoved away after the queue is complete, and thus you don't get your delegate callbacks. The connection has to be in the main queue so it stays in the run loop for callbacks to occur. Or, in your case, create it's own run loop.

    If you don't want to deal with runloops, all you have to do is put the connection on the main queue:

    dispatch_async(dispatch_get_main_queue(), ^(void){
        conn =  [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:NO];
        [conn start];
    }
    

    Then you should get your delegate callbacks.