title: How can I run an iOS voip app in the background without external signaling?
body: <p>I'm developing a voip app for iPad. I know there are similar questions, but none of the offered solutions have worked so far. I already know that I have to set the voip flag in the info.plist file (I used xcode for that). I have also set the "application does not run in the background" to "no" (who made up that name?!?). I also configured the socket as voip using the following two lines:  </p>
  
  <pre><code>CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
  CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
  </code></pre>
  
  <p>I read through the documentation and countless posts on SO and other forums, and there seem to be a few ways to get an app to run in the background forever. I have tried the following:  </p>
  
  <p>Start a long running background task, and restart the task when it fires. It was explained here on SO somewhere, but I can't find the post anymore so here is the pseudocode:  </p>
  
  <pre><code>expirationHandler = ^{
      if (inBackground) {
          [[UIApplication sharedApplication] endBackgroundTask:bgTask];
          bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:expirationHandler];
      }
  };
  
  inBackground = true;
  bgTask = UIBackgroundTaskInvalid;
  bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:expirationHandler];
  
  // Start the long-running task and return immediately.
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  
      // inform others to stop tasks, if you like
      [[NSNotificationCenter defaultCenter] postNotificationName:@"MyApplicationEntersBackground" object:self];
  
      inBackground = true;
      while (inBackground) {
          //send a keep alive to my server
          sleep(5);
      }
  });
  </code></pre>
  
  <p>The second thing I tried was to use setKeepAliveTimeout like this:  </p>
  
  <pre><code>[[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{
      //send a keep alive to my server
  }];
  </code></pre>
  
  <p>The first one seems to work very well (note that battery life and app-store approval are of no concern to me), but only when the application runs from xcode. When I put the app on the device and run it without debugger, the app stays alive for about 3 minutes and then it dies.  </p>
  
  <p>The second one seems to be how it is supposed to be, but my problem with it is that it has a minimum time of ten minutes. My server closes the connection after ten minutes of inactivity and setKeepAliveTimeout seems to be a bit inaccurate, so sometimes it is off by half a second or so (I've experienced 2 seconds one time). This means that once every ten minutes there is a chance that my session to the server is closed.<br>
  I use a protocol called XIMSS, used by the Communigate Pro server platform. Most voip apps seem to use SIP, which can send keep alive packets from the server, but that is not a option for me. So how can I make sure my app always wakes in time to send a keep alive? Is there anything that has an interval smaller than ten minutes?</p>