I used this method to get the desired location accuracy (in SWIFT)
let TIMEOUT_INTERVAL = 3.0 func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { let newLocation = locations.last as! CLLocation println("didupdateLastLocation \(newLocation)") //The last location must not be capured more then 3 seconds ago if newLocation.timestamp.timeIntervalSinceNow > -3 && newLocation.horizontalAccuracy > 0 { var distance = CLLocationDistance(DBL_MAX) if let location = self.lastLocation { distance = newLocation.distanceFromLocation(location) } if self.lastLocation == nil || self.lastLocation!.horizontalAccuracy > newLocation.horizontalAccuracy { self.lastLocation = newLocation if newLocation.horizontalAccuracy <= self.locationManager.desiredAccuracy { //Desired location Found println("LOCATION FOUND") self.stopLocationManager() } } else if distance < 1 { let timerInterval = newLocation.timestamp.timeIntervalSinceDate(self.lastLocation!.timestamp) if timerInterval >= TIMEOUT_INTERVAL { //Force Stop stopLocationManager() } } }
Where:
if newLocation.timestamp.timeIntervalSinceNow > -3 && newLocation.horizontalAccuracy > 0 {
The last location found should not be recorded more than 3 seconds ago, and the last location must have the correct horizontal accuracy (if less than 1 means that this is not a valid location).
Then we will set the distance with the default value:
var distance = CLLocationDistance(DBL_MAX)
Calculate the distance from the last location to a new place:
if let location = self.lastLocation { distance = newLocation.distanceFromLocation(location) }
If our local last location has not yet been established, or if the new horizontal location is better than the actual one, then we are going to set the local location to a new location:
if self.lastLocation == nil || self.lastLocation!.horizontalAccuracy > newLocation.horizontalAccuracy { self.lastLocation = newLocation
The next step is to check if the accuracy is correctly obtained from the location. To do this, we check to see if the horizontal distance of the location has changed, and then the desired value. If this is the case, we can stop our manager:
if newLocation.horizontalAccuracy <= self.locationManager.desiredAccuracy { //Desired location Found self.stopLocationManager() }
With the last if we will check if the distance from the last found location is removed, and the new location is less (this means that 2 locations are very close). If so, then we are going to get the time interval from the last found location and get a new location and check if the interval exceeds more than 3 seconds. If this is the case, it means that for more than 3 seconds we are not getting a location that is more accurate from our local location, and therefore we can stop the location services:
else if distance < 1 { let timerInterval = newLocation.timestamp.timeIntervalSinceDate(self.lastLocation!.timestamp) if timerInterval >= TIMEOUT_INTERVAL { //Force Stop println("Stop location timeout") stopLocationManager() } }