4

I'm currently writing an application which depends on location tracking and sending data about the position to the server. The problem, however, is that it has to run 24/7 and currently I'm experiencing random crashes which occur every 2-3 days. What I have done to make the application run constantly in the background is I put a NSTimer in a beginBackgroundTaskWithExpirationHandler method right iside the applicationDidEnterBackground method. The timer executes each minute and stops/starts the location service.

Here is a sample crash log

The code basically looks like this:

UIApplication *app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTaskId = 0;

bgTaskId = [app beginBackgroundTaskWithExpirationHandler:^{
    NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 1 * 60.0 target: self selector: @selector(onTick) userInfo: nil repeats: YES];
    [t fire];

    if (bgTaskId != UIBackgroundTaskInvalid){
        [app endBackgroundTask: bgTaskId];

        bgTaskId = UIBackgroundTaskInvalid;
    }
}];

I am using GCDAsyncSockets for connection purposes, each call having a timeout of approximately 30 seconds.

I'm really out of ideas, what might be the reason the crashes occur?

Robus
  • 8,067
  • 5
  • 47
  • 67
az4dan
  • 651
  • 2
  • 10
  • 30
  • 1
    https://developer.apple.com/library/IOs/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html This link is the doc for the multitasking and background stuff. It might hold the info we all seek. – Kaili May 22 '12 at 16:41
  • 1
    Yea I did this an app once, you might want to use NSRunLoopCommonModes for your timer – Greg Price May 22 '12 at 16:50
  • 1
    Have you looked at the WWCD 2010 session "Using Core Location in iOS 4" and the associated sample app "Breadcrumbs"? http://developer.apple.com/videos/wwdc/2010/ They describe how to use Core Location while backgrounded without using any timer tricks. – Jenn May 24 '12 at 20:55

1 Answers1

4

Your timer is probably firing off AFTER the task is invalidated (after [UIApplication sharedApplication].backgroundTimeRemaining gets to 0.

The thing is that you can't make the application run constantly in the background. If you want to execute code every once in a while, your only option is going to be using the background location API, setting that your app is using the location background mode in its plist. You would be getting the CLLocationManagerDelegate callbacks, and you have some time to do some work when those methods are called.

See the Apple documentation regarding background modes: http://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

And the location-awarness manual: http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/LocationAwarenessPG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009497

Javier Soto
  • 4,840
  • 4
  • 26
  • 46