Get Location Updates for iOS App Even when Suspended
Asked Answered
N

2

32

On early 2014, Apple has updated the iOS 7.0 to 7.1 in order to allow location updates even when the app is not active on foreground and not in the background. How do we do that?

I have read some articles like Apple's iOS 7.1 will fix a geolocation bug. But Apple didn't provide much communication related to that nor any sample code on how to get the location update even when the app is killed/terminated/suspended.

I have read the Release Notes for iOS 7.1. I couldn't find anything related to that as well.

So, how do we actually get the location update for iOS 7 and 8 even when the app is suspended?

Norenenorfleet answered 2/1, 2015 at 13:1 Comment(0)
N
80

After months of trials and errors by experimenting the Core Location Framework, I have found the solution to get location update even when the app is killed/suspended. It works well for both iOS 7 and 8.

Here is the solution:-

If your app is a location based mobile application that needs to monitor the location of the device when it has significant changes, the iOS will return you some location coordinates when the device has moved more than 500 meters from the last known location. Yes, even when the app is killed/suspended either by the user or iOS itself, you still can get the location updates.

So in order for a locationManager to get location update even when the app is killed/suspended, you must use the method startMonitoringSignificantLocationChanges, you can not use startUpdatingLocation.

When iOS wants to return the location update to the app, it will help you to relaunch the app and return a key UIApplicationLaunchOptionsLocationKey to the app delegate method didFinishLaunchingWithOptions.

The key UIApplicationLaunchOptionsLocationKey is very important and you must know how to handle it. You must create a new locationManager instance when you receive the key and you will get the location update on the locationManager delegate method didUpdateLocations.

Here is the sample code:-

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    self.shareModel = [LocationShareModel sharedModel];

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { 
      self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
      self.shareModel.anotherLocationManager.delegate = self;
      self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
      self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;

      if(IS_OS_8_OR_LATER) {
        [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
      }

     [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];   

    }    
        return YES;
 }

In addition to the didFinishLaunchingWithOptions method, I have created the locationManager instance when the app is active. Here are some code examples:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];

    if(IS_OS_8_OR_LATER) {
        [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
    }

    [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(self.shareModel.anotherLocationManager)
        [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];

    self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
    self.shareModel.anotherLocationManager.delegate = self;
    self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;

    if(IS_OS_8_OR_LATER) {
        [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
    }

    [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}

I have written an article explaining on the details on how to get the location update for iOS 7 and 8 even when the app is killed/suspended. I have also uploaded the complete source code on GitHub with the steps on how to test this solution.

Please visit the following URLs for more information:-

  1. Getting Location Updates for iOS 7 and 8 when the App is Killed/Terminated/Suspended
  2. Source Code on GitHub - Get the Location Updates Even when the iOS mobile apps is Suspended/Terminated/Killed
Norenenorfleet answered 2/1, 2015 at 13:1 Comment(10)
"You must create a new locationManager instance when you receive the key" - sounds a bit confusing, do you mean exactly "NEW locationManager instance" ? I have a shared instance of locationManager in my project - can I just reuse it ?Luteous
Good question. When the app is suspended, the shared locationManager that you have created earlier will be flushed out from the memory as well. How do you reuse an instance that does not exist in the memory? So, creating a new instance is the only way.Norenenorfleet
Hi Ricky, great answer. Just one question: Can the same method be applied to the standard location manager as opposed to just the significant change location manager?Whittling
Is it possible to save locations and logs with core data when app is terminated or only in .plist file?Buckjumper
Does this work when the distance filter is relatively small? Say 50 meters?Rooster
@Ricky... please see this....#37338966Thoer
@Norenenorfleet Im not getting Accurate location if I use "startMonitoringSignificantLocationChanges" Where as getting Accurate one if I use "startUpdatingLocation".Cano
@Ricky, I want to use both "startUpdatingLocation" "startMonitoringSignificantLocationChanges". Will this work in suspended state.Cano
@Ricky, thanks for the explanation. This part is poorly documented. However, I don't understand why you stop and start again significant location changes when the app enters background, and why do you recreate it when the app becomes active again. Is it mandatory, a just a double precaution?Swift
Hi, I have tried but its not working, I tried with iOS 11, is this working only in iOS 7&8 or 7 and above lates version.Feverroot
B
0
locationManager = [[CLLocationManager alloc] init];
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)


if(IS_OS_8_OR_LATER)
{
    [locationManager requestWhenInUseAuthorization];
}

locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;

[locationManager startUpdatingLocation];

that code user location update only forground app running but not background run

[locationManager requestWhenInUseAuthorization];
Betwixt answered 13/8, 2015 at 13:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.