Brandon
Brandon

Reputation: 2171

Call a localNotification if user enters/exits region while app is in background

I need to perform the simple task of calling a localNoification if the user enters or exits a region while the app is in background mode. Only a single set of coordinates will trigger the notification. For example:

Lat: 41.8500 Lon: 87.6500 Radius: 300

I know how to call the localNotification, and how to use the basic functionality of the locationManager, but cannot seem to track the location in the background. Any help would be great!

Upvotes: 0

Views: 843

Answers (2)

Peter E
Peter E

Reputation: 4931

Have you read up on CLLocationManager's startMonitoringForRegion: method? I think this will do exactly what you want. The code to set it up would look something like this:

CLRegion * region = [[CLRegion alloc] initCircularRegionWithCenter: CLLocationCoordinate2DMake(41.8500, 87.6500) radius: 300 identifier: @"regionIDstring"];
CLLocationManager * manager = [[CLLocationManager alloc] init];
[manager setDelegate: myLocationManagerDelegate];
[manager startMonitoringForRegion: region];

After that, the device will monitor for entrances/exits to the specified region, even when your app is in the background. When a region is crossed, the delegate will receive a call locationManager:didEnterRegion: or locationManager:didExitRegion:. You can use this opportunity to post a UILocalNotification. If your app is not running at the time the region is crossed, it will be launched in the background, and you will need to look for the appropriate key in application: didFinishLaunchingWithOptions:. Use code like the following:

if ([launchOptions objectForKey: UIApplicationLaunchOptionsLocationKey] != nil) {
    // create a location manager, and set its delegate here
    // the delegate will then receive the appropriate callback
}

Be aware that the app will only have a short amount of time to execute while running in the background (a few seconds); if you need to perform a longer task, call the beginBackgroundTaskWithExpirationHandler: method that Nebs mentioned in his/her answer immediately after your app is notified of the region crossing. This will give you about 600 seconds to run in the background.

Upvotes: 3

nebs
nebs

Reputation: 4989

Have a look at the beginBackgroundTaskWithExpirationHandler: method of UIApplication. It allows you to request additional time to run a task when the app is in the background.

For more information I suggest you read the "Background Execution and Multitasking" section of the iOS app programming guide. It explains in detail what happens when the app goes in background and what you're allowed to do.

Specifically it shows this sample code of running a long task when the app goes in the background:

[ This code is taken from the Apple guide linked above ]

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    bgTask = [application 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), ^{

        // Do the work associated with the task, preferably in chunks.

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

Upvotes: 2

Related Questions