locationManager didUpdateLocations fires twice on device, only once on simulator

The best way is do as following:

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

Location Manager delegate methods can be called very frequently and at any time.

You may however, apply following algorithm to safeguard yourself:

  1. Create a global bool say didFindLocation.
  2. Set didFindLocation to false when you call startUpdatingLocation.
  3. Inside delegate call back didUpdateLocations:, if didFindLocation was false, set didFindLocation to true and then call stopUpdatingLocation.

Hope this helps.


After getting 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 the object of CLLocationManager.


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 don't forget to set the delegate again.