LocationManager didUpdateLocations fires twice on the device, only once on the simulator

The same code, I assume that the device actually updates the location twice for some reason, although I only call startUpdatingLocation () once and I run some stopUpdatingLocations () inside doUpdateLocations

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { manager.stopUpdatingLocation() let loc: CLLocation = locations[locations.count - 1] let id = 0 let type = 0 let number = 0 createNewDataPoint(id, loc: loc, type: type, number: number) } 

In this case, createNewDataPoint is called twice, creating 2 new datapoints. This happens only once in the simulator, so I assume this has something to do with the actual device and GPS, as the simulator fakes its location.

startUpdatingLocation () only in my code once, per button. Basically, you press the button, go go manager.startUpdatingLocations (), didUpdateLocations hits once on the simulator, twice on the device (identical coordinates) and creates 2 new data points.

The only other code that mentions anything is related to setting accuracy, filter, authorization requests and the previously mentioned startUpdatingLocation (). Is there something I can do to make sure that I don't create twice as many data points as needed?

+8
ios swift cllocationmanager
source share
8 answers

You can invoke location manager delegation methods very often and at any time.

However, you can apply the following algorithm to protect yourself:

  • Create a global bool let's say didFindLocation .
  • Set didFindLocation to false when you call startUpdatingLocation .
  • The didUpdateLocations: delegate internal call didUpdateLocations: if didFindLocation was false , set didFindLocation to true and then call stopUpdatingLocation .

Hope this helps.

+11
source share

The best way is to do the following:

 func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { manager.stopUpdatingLocation() manager.delegate = nil } 
+7
source share

Best Solution for iOS 10.0 +

 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { [locationManager stopUpdatingLocation]; // stop location manager locationManager.delegate = nil; //Your logics... //This will be called only one time now. } 

But remember to set the delegate again.

+5
source share

You will not play the simulator often. and on the device, when you move far, then you only get didUpdateLocations . just move in the open, so the GPS can identify your device location so that it gets the best accuracy.

0
source share

Instead of starting / ending the location update and setting the delegate to zero, there is a method called requestLocation , which is ideal when your application needs a quick fix in the user's location:

From the docs:

 override func viewDidLoad() { // Create a location manager object self.locationManager = CLLocationManager() // Set the delegate self.locationManager.delegate = self } func getQuickLocationUpdate() { // Request location authorization self.locationManager.requestWhenInUseAuthorization() // Request a location update self.locationManager.requestLocation() // Note: requestLocation may timeout and produce an error if authorization has not yet been granted by the user } func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { // Process the received location update } 

Use this method if you want the user to have the current location, but do not need to leave location services.

0
source share

@ Zumry Mohamed's solution is correct.

I try the code as follows:

 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { [self.locationManager stopUpdatingLocation]; self.locationManager.delegate = nil; self.locationManager = nil; } 

finally, this delegate is called only once, now I understand why the problem arises, simply because the manager calls the stopUpdatingLocation method, but the system does not help us invalidate the delegate, so we can get a call to update your location every time because of your setting the desiredAccuracy and distanceFilter properties of your CLLocationManager , so the final solution is similar to what @Zumry Mohamed said, we can manually set the delegate to zero when we stopUpdateLocation . Hope this helps you understand what is happening, why this might solve the problem.

0
source share

After obtaining the desired latitude and longitude, just call stopUpdatingLocation() and set the delegate to nil .

In Swift 3:

 locationManager.stopUpdatingLocation() locationManager.delegate = nil 

In Objective-C:

 [locationManager stopUpdatingLocation] locationManager.delegate = nil 

Here locationManager is a CLLocationManager object.

0
source share

locationManager.startUpdatingLocation () retrieves the location continuously and the doUpdateLocations method calls several times. Just set the value for the locationManager.distanceFilter parameter before calling locationManager.startUpdatingLocation ().

How I set 200 meters (you can change as your requirement), working fine

  locationManager = CLLocationManager() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.distanceFilter = 200 locationManager.requestWhenInUseAuthorization() locationManager.startUpdatingLocation() 
0
source share

All Articles