2

I am using CLLocationManager and MKMapView in same UIViewController. I want to call an API only when the significant location change.

import UIKit
import CoreLocation
import MapKit


class ViewController: UIViewController,CLLocationManagerDelegate,MKMapViewDelegate {

@IBOutlet weak var mapView: MKMapView!

var locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.locationManager.requestAlwaysAuthorization()
    self.locationManager.delegate = self
    self.locationManager.startMonitoringSignificantLocationChanges()
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
    self.locationManager.distanceFilter = 500
    mapView.showsUserLocation = true
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("locations \(locations)")
 }

}

In this, the main issue is whenever I make the app background and foreground didUpdateLocations get called. I want it to be called only when significant location change, not every time when viewWillAppear called.

I found its because of MKMapView, didUpdateLocations is being called.

Arjun Yadav
  • 1,369
  • 1
  • 10
  • 23
Cintu
  • 913
  • 2
  • 16
  • 32
  • Why do you have `self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation` if you only want significant location updates? Are you displaying the user location on your map view? – Paulw11 Aug 09 '17 at 07:10
  • @Paulw11 - Yes i am displaying the user location in MapView – Cintu Aug 09 '17 at 07:12
  • This will cause the map to request a user location update, which is being delivered to your delegate. You can keep a record of your previous location and check the distance in the location update; only update the server when the distance is greater than some threshold – Paulw11 Aug 09 '17 at 07:13
  • https://stackoverflow.com/questions/22292835/how-to-stop-multiple-times-method-calling-of-didupdatelocations-in-ios – Salman Ghumsani Aug 09 '17 at 07:15

2 Answers2

1

You can manually check the distance with last saved location. Try this.

var lastLocation: CLLocation?
public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    if let lastLocation = lastLocation, let newLocation = locations.last {
        if (lastLocation.distance(from: newLocation) < manager.distanceFilter) {
            return
        }
    }

    print("locations \(locations)")
    lastLocation =  locations.last
}
Bilal
  • 18,478
  • 8
  • 57
  • 72
0

You can save the last locations and check inside didUpdateLocations method, if not same the take appropriate action.

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

    let location : CLLocation = locations.last!

    if location.coordinate.latitude != lastLat && location.coordinate.longitude != lastLon{
        // take action
    }
}
vaibhav
  • 4,038
  • 1
  • 21
  • 51