Aleksander
Aleksander

Reputation: 2815

MKDirections calculate directions when app is in the background

I want to calculate directions to a destination when my app is in the background every time it receives a location update.

However, the [MKDirections calculateDirectionsWithCompletionHandler] is an asynchronous call, and my question is therefore: will my app be terminated if this takes more than 5 seconds to complete after my app has received a location update? What would be your recommendations to make sure this request has enough time to finish?

Upvotes: 0

Views: 294

Answers (1)

Lyndsey Scott
Lyndsey Scott

Reputation: 37290

In order to request extra time for your app to run in the background to complete its tasks (asynchronous or not), you can use beginBackgroundTaskWithExpirationHandler:.

For example:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {

    // If the application is in the background...
    if([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) {

        // Create the beginBackgroundTaskWithExpirationHandler
        // which will execute once your task is complete
        bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
            // Clean up any unfinished task business by marking where you
            // stopped or ending the task outright.
            [application endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
        }];

        // Start the long-running task and return immediately.
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
            [dict setObject:application forKey:@"application"];

            // Start a timer to keep the program alive for 180 seconds max
            // (less if that's all that's necessary)
            [NSTimer scheduledTimerWithTimeInterval:180 target:self selector:@selector(delayMethod:) userInfo:nil repeats:NO];

        });

    }

    // ... the rest of your didUpdateToLocation: code ...

}

- (void)delayMethod:(NSTimer*)timer {

    // End the background task you created with beginBackgroundTaskWithExpirationHandler
    [[[timer userInfo] objectForKey:@"application"] endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}

Upvotes: 1

Related Questions