mobileideafactory
mobileideafactory

Reputation: 1670

CLLocationManager last known location

To get the last know geolocation, I have:

CLLocationManager * locationManager = [[CLLocationManager alloc] init];
CLLocation * lastKnownLocation = [locationManager location];

Does the lastKnownLocation reflect the last location my app has been called back with or does it reflect a global iOS system level last location (which other app or the iOS might have queried for)?

I am doing this instead of actively querying for user's location so I don't waste the user's battery.

If user has not given permission to access location, obviously lastKnownLocation should be nil. My question is specifically for the case where user has given my app permission to access location.

Upvotes: 15

Views: 7415

Answers (3)

Izabella Melo
Izabella Melo

Reputation: 285

I had the same question now in 2023 😅 and I still couldn't find any good response using Apple Docs or Google. I also tried to ask it for ChatGPT and the answer was

The lastLocation variable in your code reflects the last known location that your app has received through the CLLocationManager object. This means that it represents the location that your app has acquired, rather than a system-level location that other apps or the iOS might have queried for.

But I also wanted to make a test using the iOS simulator. I made two apps with different bundle ids.

App A has two buttons each of them with the following functionalities:

  • First button: Ask for a location using locationManager.requestLocation() and print the result in func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]
  • Second button: Print the last location using locationManager.location

App B has only one button with the following functionality:

  • Ask for a location using locationManager.requestLocation() and print the result in func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]

After that, I followed these steps:

  1. Run App A in the iOS simulator
  2. Set simulated location (Features > Location > Custom location) to eg. (-10, -20)
  3. Request a fresh location (First button). The app gives me the following:

new location: [<-10.00000000,-20.00000000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 18/04/2023 10:45:53 Horário Padrão de Brasília]

  1. Request the last location (Second button). The app gives me the following:

last location: Optional(<-10.00000000,-20.00000000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 18/04/2023 10:45:53 Horário Padrão de Brasília)

  1. Run App B in the same iOS simulator

  2. Set simulated location (Features > Location > Custom location) to eg. (30, 40)

  3. Request a fresh location. The app gives me the following:

[<+30.00000000,+40.00000000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 18/04/2023 10:48:44 Horário Padrão de Brasília]

  1. Run app A again

  2. Request the last location again (Second button). The app gives me the following:

last location: Optional(<+30.00000000,+40.00000000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 18/04/2023 10:48:44 Horário Padrão de Brasília)

  1. Change the simulated location (Features > Location > Custom location) to eg. (5, 5). The app gives me the following:

last location: Optional(<+30.00000000,+40.00000000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 18/04/2023 10:48:44 Horário Padrão de Brasília)

So, if the device follows the simulators, locationManager.location should give us a global iOS system level last location.

Upvotes: 3

Maurits van Beusekom
Maurits van Beusekom

Reputation: 6009

I know this is an old question but for the sake of being complete and maybe others ending up here:

The CLLocationManager class has the location property which returns (according to official Apple docs):

The most recently retrieved user location.

This method will return nil when no location is known.

Upvotes: 1

Wain
Wain

Reputation: 119041

Generally you should not simply rely on the existing (if any) value returned from location unless you check its accuracy and time stamp (compared to your requirements). It's better to start startUpdatingLocation until you get a location which does match your accuracy requirements and then either stopUpdatingLocation or switch to stopMonitoringSignificantLocationChanges (if available).

The location returned from location is very dependent upon history, so you can't definitely say one way or the other that it will be. You always need to verify the accuracy for your purposes.

Upvotes: 5

Related Questions