0

I have added background process support to my app using the below code before I ping the server:

UIApplication *app = [UIApplication sharedApplication];
        bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
            [app endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
        }];
        if (!connection) {
            connection = [[NSURLConnection alloc] init];
        }
        (void)[connection initWithRequest:originalRequest delegate:self];

Because of this code if I keep the application in background mode more than 10mins it is crashing. As per my understanding I should not allow tasks to run in background continuously, I should set some time interval for each task. But I don't know how to set the time interval to kill them.

Please suggest me some steps to solve this issue.

Dee
  • 1,887
  • 19
  • 47
  • 1
    Actually you can not set the expiration time to some discrete values. It is managed by iOS. IOS will stop your background tasks itself after it expires. Which is 10mins prior iOS7, and 3mins with iOS7, if I'm right. And you never should try to kill your app manually. How does your app crash? Do you mean it gets relaunched? Please refer here for more info: http://stackoverflow.com/questions/18247808/what-is-the-proper-way-to-handle-background-tasks-in-ios – ambientlight Oct 11 '13 at 10:59
  • I launched the application and clicked on home button, when I try to relaunch the app after 10mins it starts from the first screen – Dee Oct 11 '13 at 11:07
  • Set a timeout for the request in the NSURLRequest. Assuming it's not a big file that should be enough. Look at background transfer in iOS 7 if you need a long download. Tasks added to a background session are run in an external process and continue even if your app is suspended, crashes, or is killed. – Jano Oct 11 '13 at 11:39
  • I have added that also. 80 seconds . – Dee Oct 11 '13 at 12:43

1 Answers1

1

There are several important points here, many of which have already been covered in the comments.

Firstly, time you have is not known. There are empirical values (10 minutes before iOS 7/ 3 minutes with iOS 7), but these are not guaranteed. In particular, if you wake from sleep to do work (e.g. geofenced alert), you may not get the full time, you may only get the time remaining from your last time. There are particular actions you can take that will reset the time (e.g. getting your location with GPS may reset the timer in some versions of iOS).

Secondly, you're not being killed because you're still doing work, you're being killed because you have told the OS you're still doing work. The OS doesn't care about your network transfer, it cares about your beginBackgroundTaskWithExpirationHandler.

You can verify this from the crash report, which will say "has active assertions beyond permitted time"

There are three possible reasons for this.
1) The OS called your completion handler, but you didn't call endBackgroundTask in time. You don't get much time when the background handler gets called, but I doubt that this is the problem, your code is pretty compact.

2) The OS called your completion handler, but you didn't call endBackgroundTask at all. I've inherited code that does this, the normal reason is that the code isn't re-entrant, and it is called twice. bgtask is updated to the second value, so when the completion handlers fire, bgtask is ended twice for one task and never for the other. Again, I think you're safe, this is normally a problem for member variables, in your case, bgtask should be copied by the block.

3) The OS didn't call your background handler ( unlikely, but I have some probably unfounded suspicions about iOS 7).

The next possibility, which is not really a background execution issue is that you're not really crashing. Run your app disconnected from Xcode and see if it generates a crash report. If it doesn't, you're probably just being ejected due to memory pressure. If this is really a too long in the background issue, you'll see the exception code is 0x0badfood. Bad food is what makes the watchdog timer angry.

I think background processes used to be removed from the background apps when they were quietly ejected, but now the OS replaces them with a screenshot and starts them anew if the user brings them to the foreground.

Gordon Dove
  • 2,537
  • 1
  • 22
  • 23