4

I have set up the following method:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

It is working correctly and is being called, but it never contains more than one location. I am trying to get the distance between the new and old location when the phone moves. Am I missing something? There are never two items in the locations array.

Lyndsey Scott
  • 37,080
  • 10
  • 92
  • 128
jdog
  • 10,351
  • 29
  • 90
  • 165

3 Answers3

6

As the documentation for didUpdateLocations says the array is ...

... An array of CLLocation objects containing the location data. This array always contains at least one object representing the current location. If updates were deferred or if multiple locations arrived before they could be delivered, the array may contain additional entries. The objects in the array are organized in the order in which they occurred. Therefore, the most recent location update is at the end of the array.

Generally you're right and there is often only one location, so you should keep track of your own property where you'll store the last valid location you received from the last time didUpdateLocations was called.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Ok thanks this was my second thought, but was hoping iOS would do that for you, thus the array. – jdog Dec 30 '14 at 04:30
  • Nope. It's easy enough to compare the location to the previous location using `distanceFromLocation` method (though make sure both locations have non-negative `horizontalAccuracy`) and then update the saved location with the current location. – Rob Dec 30 '14 at 04:38
1

You're doing this right. Usually, locationManager:didUpdateLocations: will have only one location, especially when your app is foregrounded, location services have been recently active, etc.

It can, though, have multiple locations - typically in less usual circumstances, e.g. if your app was started for a background location update and additional ones come in while it is starting up.

So don't sweat it. But in any case, you'll want to keep track of the 'old' location yourself - it's not the case that the array would contain historical locations that happen to be the ones you want. Rather, it's more likely to be 'stale' data that may suffice in some circumstances, or stacked up updates.

Added: To keep track of how the phone is moving, you'll want to keep your own CLLocation variable in the class where you're tracking location. You will need to determine what business logic you want to implement. If you want literally the distance between every update and the last one, just add a variable called lastLocation and use CLLocation's distanceFromLocation: to get the difference. (See the docs at Apple's developer site for more info.)

But I doubt that's quite what you want. Then you may get 1 meter each time, and never really know if you've gone 1000 meters in one direction. . . . or bounced back and forth and stayed in the same spot.

Probably you'll need to have some sort of minimum timestamp - so when a new update comes in, compare theNewLocation.timestamp to theOldLocation.timestamp and only measure the distance if, say, it's been at least ten minutes.

(If you do something longer than a few seconds, you're best off turning off location updates in between.)

Or, perhaps, there is some other logic you want to use. For example, getting the distance only when the new location is a different city than the previous one, or adding the new location to an array when it's finally at least 500 meters from the old one, or etc. This, too, falls under depending heavily on what you want to do with the data.

tooluser
  • 1,481
  • 15
  • 21
0

Looks like to:from was deprecated and based on the description in the docs, you may want to manually preserve your old location.

I don't read the multiple items case (emphasis mine) as being what you imply you want.

An array of CLLocation objects containing the location data. This array always contains at least one object representing the current location. If updates were deferred or if multiple locations arrived before they could be delivered, the array may contain additional entries. The objects in the array are organized in the order in which they occurred. Therefore, the most recent location update is at the end of the array.

[EDIT]

As far as actually getting the distance, check this answer: Calculating Distance between two coordinates using CLLocation

Community
  • 1
  • 1
Brad Brighton
  • 2,179
  • 1
  • 13
  • 15