Nicolai Harbo
Nicolai Harbo

Reputation: 1169

CLLocationManager is slow getting location, Swift

Im creating this app, and it needs to get the users location - its all working properly, the thing is, that the time from accepting the use of location services, to getting the actual location takes like 5 seconds - is this normal? I've used other apps, where it goes much faster..

Here's what my code looks like:

override func viewDidLoad() {
    super.viewDidLoad()

    // Ask for Location-Authorisation from the User.
    self.locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.requestLocation()
    }

    mapView.delegate = self

}



func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let locValue: CLLocationCoordinate2D = manager.location!.coordinate

    let initialLocation = CLLocation(latitude: locValue.latitude, longitude: locValue.longitude)

    self.centerMapOnLocation(initialLocation)
}

func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
    print("could not get location")
}

But the time from the application gets the location to put into the centerMapOnLocation-function, seems just to be quite long. What is to be expected, when getting a users location? I'm testing on a wifi connection, so I know its not because the internet is slow, or its a bad connection...

Anyone have an idea? :)

Best regards!

Upvotes: 16

Views: 7722

Answers (4)

ctrl freak
ctrl freak

Reputation: 12385

If you don't want to delay the app's launch for the location manager, consider deploying two location managers (in the app delegate), tasking one with generating a location quickly and the other with generating a location accurately:

fastLoc.delegate = self
fastLoc.desiredAccuracy = kCLLocationAccuracyThreeKilometers
fastLoc.requestWhenInUseAuthorization()
fastLoc.startUpdatingLocation()

bestLoc.delegate = self
bestLoc.desiredAccuracy = kCLLocationAccuracyBest
bestLoc.requestWhenInUseAuthorization()
bestLoc.requestLocation()

The combination of 3 km accuracy with startUpdatingLocation() should return a location almost instantly, almost always before the root view controller is even ready to go. bestLoc manager is likely to return a location well after the user has launched the app but it will be very accurate.

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    switch manager {
    case fastLoc:
        fastLoc.stopUpdatingLocation()
        deviceLocation = locations.last! // set property with fast loc
        
    case bestLoc:
        deviceLocation = locations.last! // overwrite property with best loc
    default:
        break
    }
}

Upvotes: 2

LineDrop
LineDrop

Reputation: 489

When initializing your location manager, add startUpdatingLocation():

let manager = CLLocationManager()
 manager.delegate = self
 manager.requestWhenInUseAuthorization()
 manager.requestLocation()
 manager.startUpdatingLocation()

Without startUpdatingLocation() geo-location takes about 5 seconds, with it, the request executes nearly immediately.

Upvotes: 3

Jens Peter
Jens Peter

Reputation: 765

Try setting the accuracy and use locationManager.startUpdatingLocation(). I do that, and get answer within a second (on the device).

Upvotes: 22

user3581248
user3581248

Reputation: 1014

From the documentation of requestLocation():

This method returns immediately. Calling it causes the location manager to obtain a location fix (which may take several seconds) and call the delegate’s locationManager(_:didUpdateLocations:) method with the result.

Source

So basically, everything is fine with your code, it's just how the framework is built.

Upvotes: 8

Related Questions