Article

Using the Standard Location Service

Get regular location updates based on the parameters you specify.

Overview

When you need the most control over location updates, use the standard location service. This service is highly configurable, letting you specify the preferred accuracy for locations and the distance that the user must travel before new updates are delivered. This service is most commonly used by apps that require high precision locations or frequent updates, such as navigation apps. Because it offers higher accuracy, the service typically consumes more power than the other location services.

To start the standard location service, configure your CLLocationManager object and call its startUpdatingLocation() method. The location manager delivers updates to the locationManager(_:didUpdateLocations:) manager of its delegate. Listing 1 shows how to check for the availability of the standard location service and configure it for use.

Listing 1

Starting the standard location service

let locationManager = CLLocationManager()
func startReceivingLocationChanges() {
   let authorizationStatus = CLLocationManager.authorizationStatus()
   if authorizationStatus != .authorizedWhenInUse && authorizationStatus != .authorizedAlways {
      // User has not authorized access to location information.
      return
   }
   // Do not start services that aren't available.
   if !CLLocationManager.locationServicesEnabled() {
      // Location services is not available.
      return
   }
   // Configure and start the service.
   locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
   locationManager.distanceFilter = 100.0  // In meters.
   locationManager.delegate = self
   locationManager.startUpdatingLocation()
}

To minimize power consumption, never set the desiredAccuracy property to a higher accuracy than what you actually need. Similarly, always set the distanceFilter property to the greatest value that meets the needs of your app. The system always tries to give you the best location data that is available, but these properties give the system the flexibility to turn off hardware elements when they are not needed. For example, if you set the desired accuracy to kCLLocationAccuracyKilometer, the system might disable GPS and use only the Wi-Fi hardware, which would save power and still give you a greater accuracy than you requested.

Another way to save power is to set the pausesLocationUpdatesAutomatically property of your location manager object to true. Enabling this property lets the system reduce power consumption by disabling location hardware when the user is unlikely to be moving. For example, if the user stops for food while using a navigation app, the system might turn off GPS hardware until the user starts moving again. Pausing updates does not diminish the quality of those updates, but can improve battery life significantly. To help the system determine when to pause updates, you must also assign an appropriate value to the activityType property of your location manager.

Receiving Location Updates

When you start the standard location service, a recently cached value may be reported to your delegate immediately. As new location data is obtained, the location manager calls your delegate's locationManager(_:didUpdateLocations:) method with the updated values. The locations parameter always contains at least one location and may contain more than one. Locations are always reported in the order in which they were determined, so the most recent location is always the last item in the array, as shown in Listing 2.

Listing 2

Processing the most recent location update

func locationManager(_ manager: CLLocationManager,  didUpdateLocations locations: [CLLocation]) {
    let lastLocation = locations.last!
               
    // Do something with the location.
}

Before using a location value, check the time stamp of the CLLocation object. Because the system may return cached locations, checking the time stamp lets you know whether to update your interface right away or perhaps wait for a new location.

Handling Location-Related Errors

When the location manager is unable to deliver location updates, it calls the locationManager(_:didFailWithError:) method of its delegate object. You should always implement this delegate method to handle any errors that might occur. For example, this method is called when the user denies authorization for your app to use location services. In such a scenario, you might want to disable location-related features and notify the user which features are unavailable. You should also stop whatever service you previously started, as demonstrated in Listing 3.

Listing 3

Stopping location services when authorization is denied

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
   if let error = error as? CLError, error.code == .denied {
      // Location updates are not authorized.
      manager.stopUpdatingLocation()
      return
   }       
   // Notify the user of any errors.
}

See Also

Related Topics

Using the Visits Location Service

Get location updates in the most power-efficient way, but less frequently than with other services.

Using the Significant-Change Location Service

Get location updates in a power-friendly way, but less frequently than with the standard location service.

Handling Location Events in the Background

Take advantage of background execution modes to respond to location-related events at any time.