Rahul Gupta
Rahul Gupta

Reputation: 539

CLLocationManager didUpdateLocations is getting called many times

didUpdateLocations is getting called many times. so how i can handle stop this. I tried using locationManager.stopUpdatingLocation() in didUpdateLocations but it is not working fine.

override func viewDidLoad()
{
    super.viewDidLoad()
    //for Authorisation from the User.
    isAuthorizedtoGetUserLocation()

    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.startUpdatingLocation()
    }
}

func isAuthorizedtoGetUserLocation() {

    if CLLocationManager.authorizationStatus() != .authorizedWhenInUse     {
        locationManager.requestWhenInUseAuthorization()
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    locationManager.stopUpdatingLocation()
    let locValue:CLLocationCoordinate2D = manager.location!.coordinate
    print("locations = \(locValue.latitude) \(locValue.longitude)")

    let camera = GMSCameraPosition.camera(withLatitude: locValue.latitude, longitude: locValue.longitude, zoom: 6.0)
    let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
    self.view = mapView

    // Creates a marker in the center of the map.
    let marker = GMSMarker()
    marker.position = CLLocationCoordinate2D(latitude: locValue.latitude, longitude: locValue.longitude)
    marker.title = "name"
    marker.map = mapView

}

Udated Code with error

func locationManager( _ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    manager.stopUpdatingLocation()
    manager = nil // Here it is giving error "Cannot assign to value: 'manager' is a 'let' constant"

    var newLocation: CLLocation? = locations.last
    var locationAge: TimeInterval? = -(newLocation?.timestamp.timeIntervalSinceNow)!
    if Double(locationAge!) > 5.0 {
        return
    }
    if Double((newLocation?.horizontalAccuracy)!) < 0 {
        return
    }


    //manager = nil
    let locValue:CLLocationCoordinate2D = manager.location!.coordinate
    print("locations = \(locValue.latitude) \(locValue.longitude)")

    let camera = GMSCameraPosition.camera(withLatitude: locValue.latitude, longitude: locValue.longitude, zoom: 6.0)
    let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
    self.view = mapView

    // Creates a marker in the center of the map.
    let marker = GMSMarker()
    marker.position = CLLocationCoordinate2D(latitude: locValue.latitude, longitude: locValue.longitude)
    marker.title = "name"
    marker.map = mapView

}

Upvotes: 4

Views: 3655

Answers (3)

Martin Mungai
Martin Mungai

Reputation: 57

Set property distanceFilter to the constant distance max CLLocationDistanceMax to indicate that a new update should be triggered only after the device moves a significantly large distance.

Upvotes: 2

Canberk Ersoy
Canberk Ersoy

Reputation: 438

Another approach is this. My app I need to upload the location when changed. Even though I declare distance filter like this:

locationManager.distanceFilter = 300

When you first crate CLLocationManager or call startUpdatingLocation() it may called multiple times.

so I put them in a task queue like this:

     if let locationUploadTask = self.locationTask { // if there is a task waiting, cancel it 
            locationUploadTask.cancel()
        }

     self.locationTask = DispatchWorkItem { //create a new task for upload
            //do your task
        }

     DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1, execute: self.locationTask!) //execute the task 1 second after

this code forces your code to wait 1 second. If there is a new location update in a second, cancels the current task, starts waiting 1 second again.

Upvotes: -3

KKRocks
KKRocks

Reputation: 8322

You need to set CLLocation manager's distanceFilter property as below :

/* Notify changes when device has moved x meters.
 * Default value is kCLDistanceFilterNone: all movements are reported.
 */
self.locationManager.distanceFilter = 10.0f; // you can change as per your require ment

Upvotes: 3

Related Questions