Will iOS wake up the terminated app if it's registered with location for UIBackgroundModes? Will iOS wake up the terminated app if it's registered with location for UIBackgroundModes? ios ios

Will iOS wake up the terminated app if it's registered with location for UIBackgroundModes?

Looks like you found a workable solution and it seems like using the significant change framework would save you some battery life, so long as it is accurate enough for your purposes. Your solution is also beneficial because it allows you to juggle potentially more than the per-app limit of 20 regions allowed to be simultaneously monitored, by only monitoring those regions that you are closest to.

I need similar functionality, but don't think the significant change would be accurate enough for my app, so I dug around some more and found the following.

Per the Location Awareness Programming Guide, under "Monitoring Shape-Based Regions":

In iOS, regions associated with your app are tracked at all times, including when your app is not running. If a region boundary is crossed while an app is not running, that app is relaunched into the background to handle the event. Similarly, if the app is suspended when the event occurs, it is woken up and given a short amount of time to handle the event.

And also in "Handling Boundary-Crossing Events for a Region":

Every time the user’s current location crosses a boundary region, the system generates an appropriate region event for your app. If your app is already running, these events go directly to the delegates of any current location manager objects. If your app is not running, the system launches it in the background so that it can respond. Apps can implement the following methods to handle boundary crossings:



In my case, I just needed to fire a notification when the boundary was crossed, so I set my AppDelegate to conform to CLLocationManagerDelegate, created a locationManager property, and put this in my implementation file:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    self.locationManager.delegate = self;    return YES;}- (CLLocationManager *)locationManager{    if (!_locationManager) {        _locationManager = [[CLLocationManager alloc] init];        _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;    }    return _locationManager;}- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{    UILocalNotification *notification = [[UILocalNotification alloc] init];    notification.alertBody = NSLocalizedString(@"You crossed a boundary!", @"user crossed a boundary");    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];}

Testing shows this works without the UIBackgroundModes location key needing to be set. In this use-case, the OS handles boundary monitoring for you and then sends the event to your app just long enough to process the event. This doesn't launch the app, it just runs it in the background for a few seconds to process the boundary event, during which time you can only do relevant activities. Hope this helps someone else, too!

Yes, it will behave the same way except it will receive updates more often (and thus consume more battery).

Source: App States and Multitasking under the section Tracking the User's Location.

EDIT After re-reading, it seems that the program will be woken up from a suspended state but not a terminated one. I don't think you really need this background mode, though. It is designed for apps that need fine location info (like turn-by-turn navigation). Check out the section in the Location Programming guide about "region based" programming. The example in your comments is listed as one of the uses of this app.

EDIT AGAIN As per the discussion in the comments, the final solution seems to be setting significant location change until the user is close enough, and then switching over to fine location change (and hoping the app doesn't get terminated during that time ^^)

Once you kill the app, the location updates are sent to application

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

You need to collect the location updates inside this delegate method by looking for the launch key as below,

if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]){//Code to handle the location update}

Hope this is what your looking for. Yes you need to set the key "Required backround modes" with value "App registers for location updates" in plist.