Class

CLLocationManager

The CLLocationManager class is the central point for configuring the delivery of location- and heading-related events to your app. You use an instance of this class to establish the parameters that determine when location and heading events should be delivered and to start and stop the actual delivery of those events. You can also use a location manager object to retrieve the most recent location and heading data.

Overview

A location manager object provides support for the following location-related activities:

  • Tracking large or small changes in the user’s current location with a configurable degree of accuracy.

  • Reporting heading changes from the onboard compass. (iOS only)

  • Monitoring distinct regions of interest and generating location events when the user enters or leaves those regions.

  • Deferring the delivery of location updates while the app is in the background. (iOS only)

  • Reporting the range to nearby beacons.

To configure and use a CLLocationManager object to deliver events:

  1. Always request authorization to use location services and check to see whether the desired services are available as described in Requesting Permission to Use Location Services.

  2. Create an instance of the CLLocationManager class and store a strong reference to it somewhere in your app.

    Keeping a strong reference to the location manager object is required until all tasks involving that object are complete. Because most location manager tasks run asynchronously, storing your location manager in a local variable is insufficient.

  3. Assign a custom object to the delegate property. This object must conform to the CLLocationManagerDelegate protocol.

  4. Configure any additional properties relevant to the desired service.

  5. Call the appropriate start method to begin the delivery of events.

All location- and heading-related updates are delivered to the associated delegate object, which is a custom object that you provide. For information about the delegate methods you use to receive events, see CLLocationManagerDelegate.

Requesting Permission to Use Location Services

The use of location services requires user authorization. In addition, some location services require the presence of specific hardware on the given device. For example, heading information is available only on devices that contain a hardware compass. Prior to using location services, your app must request authorization from the user to use those services and it must check the availability of the target services. A typical sequence for using location services is as follows:

  1. Call the authorizationStatus() class method to get the current authorization status for your app.

    If the authorization status is restricted or denied, your app is not permitted to use location services and you should abort your attempt to use them.

  2. Create your CLLocationManager object and assign a delegate to it.

  3. Store a strong reference to your location manager somewhere in your app.

  4. In iOS, if the authorization status was notDetermined, call the requestWhenInUseAuthorization() or requestAlwaysAuthorization() method to request the appropriate type of authorization from the user.

  5. Depending on the services you need, call one or more of the following methods:

It is safe to start location services before the authorization status of your app is determined. Although you can start location services, those services do not deliver any data until the authorization status changes to authorizedAlways or authorizedWhenInUse. To be notified when the authorization status changes, implement the locationManager(_:didChangeAuthorization:) method in your location manager delegate.

For the services you use, configure any properties associated with that service accurately. Core Location manages power aggressively by turning off hardware when it is not needed. For example, setting the desired accuracy for location events to one kilometer gives the location manager the flexibility to turn off GPS hardware and rely solely on the WiFi or cell radios, which can lead to significant power savings.

Getting the User’s Current Location

There are two options for configuring location-related services:

  • Use the standard location service, which allows you to specify the desired accuracy of the location data and receive updates as the location changes.

  • Use the significant location change service, which provides a more limited set of tracking options but offers significant power savings over the standard location services. In iOS, this service can also launch your app as needed to deliver location updates.

The standard location service is most appropriate for apps that deliver location-related information directly to the user but it may be used by other types of apps too. To start the service, configure the desiredAccuracy and distanceFilter properties of the location manager and then call the requestLocation(), startUpdatingLocation(), or allowDeferredLocationUpdates(untilTraveled:timeout:) method. Never specify an accuracy value greater than what you need. Core Location uses the accuracy value you specify to manage power better. A higher degree of accuracy requires more precise hardware like GPS, which consumes more power.

The significant location change service is better suited for apps that want to get the user’s initial location and then only want to know when that location changes. This service requires the presence of cellular hardware and delivers events less frequently than the standard location services. To start the significant location-change service, call the startMonitoringSignificantLocationChanges() method.

Regardless of which location service you use, location data is reported to your app via the location manager’s associated delegate object. Because it can take several seconds to return an initial location, the location manager typically delivers the previously cached location data immediately and then delivers more up-to-date location data as it becomes available. Therefore it is always a good idea to check the timestamp of any location object before taking any actions. If both location services are enabled simultaneously, they deliver events using the same set of delegate methods.

Use the allowDeferredLocationUpdates(untilTraveled:timeout:) method to defer the delivery of location data when your app is in the background. It is recommended that you use this feature in situations where your app could process the data later without any problems. For example, an app that tracks the user’s location on a hiking trail could defer updates until the user hikes a certain distance and then process the points all at once. Deferring updates helps save power by allowing your app to remain asleep for longer periods of time.

Using Regions to Monitor Boundary Crossings

You can use the region-monitoring service to be notified when the user crosses a region-based boundary. Region monitoring applies both to geographical regions (represented by the CLCircularRegion class) and to beacon regions (represented by the CLBeaconRegion class). You use region monitoring to detect boundary crossings of the specified region and you use those boundary crossings to perform related tasks. For example, upon approaching a dry cleaners, an app could notify the user to pick up any clothes that had been dropped off and are now ready.

To start region monitoring, configure the appropriate region object and pass it to the startMonitoring(for:) method of your location manager. In iOS, registered regions persist between launches of your app. If a region boundary crossing occurs while your iOS app is not running, the system automatically wakes it up (or relaunches it) in the background so that it can process the event. In this case, the options dictionary passed to the application(_:didFinishLaunchingWithOptions:) method of your app delegate contains the key location to indicate that your app was launched because of a location-related event. During the relaunch process, you must recreate your location manager object and assign a delegate capable of handling region-related events. After you do that, the system delivers the region notification for which your app was launched. All of the regions you configured previously are made available in the monitoredRegions property of any location manager objects you create.

In macOS, region monitoring works only while the app is running (either in the foreground or background) and the user’s system is awake. The system does not launch apps to deliver region-related notifications. Similarly, if the user puts the computer to sleep, the system does not deliver region monitoring notifications to your app. If the user wakes up the computer inside a monitored region, the system does deliver region notifications to your app if it is running. However, if the computer enters and exits the region before being woken up, no notification is delivered.

The region monitoring service operates independently of any location services in use by your app, and you may use it in conjunction with any of the other services. Region monitoring is not supported on all devices. Use the regionMonitoringAvailable() class method to determine if region monitoring can be used.

Determining the Proximity to Beacons

You can use the beacon ranging service to determine the approximate distance to devices that support iBeacon technology. Beacon ranging involves listening for devices that are broadcasting their presence over Bluetooth LE. When you start ranging, you receive information about the identify of each beacon that is in range, including information about whether that beacon is nearby or farther away. Updates are then delivered whenever the status of a beacon changes.

To start beacon ranging, create a CLBeaconRegion object that identifies the beacons you want and pass that object to the startRangingBeacons(in:) method. As the location manager detects beacons, it delivers that information to its delegate’s locationManager(_:didRangeBeacons:in:) method. In an area where many beacons are active and the user is moving, updates may be delivered frequently. To preserve battery life, do not range for beacons all the time. The recommended practice is to use the region monitoring service to detect the presence of beacons first and to start ranging only after you detect one or more beacons. And, of course, you should stop ranging as soon as you have the information you need or when you move out of range of your beacons.

Configuring Heading-Related Services

In iOS, you can use the heading service to obtain compass-related information on devices with the appropriate hardware. Apps that implement navigation or spatial orientation features can use the compass information to determine which way a user is facing. The heading service is not supported in macOS.

To begin the delivery of heading-related events, assign a delegate to the location manager object and call its startUpdatingHeading() method. If location updates are also enabled, the location manager returns both the true heading and magnetic heading values. If location updates are not enabled, the location manager returns only the magnetic heading value.

Core Location delivers heading data to your app while it is in the foreground. When your app moves to the background, event delivery stops unless your app has the location-updates background mode enabled and the standard location service is running. You can enable background modes from the Capabilities tab of your Xcode project but should do so only if you can use heading data practically while in the background.

Getting the Visited Locations

In iOS, the visits service provides an alternative to the significant location change service for apps that need location information about interesting places that the user visited. For example, if the user is in one location for an extended period of time, the service might generate an event when the user arrives at that location and another when the user leaves that location. The service is intended for apps that might already be using the significant location change service and want an even lower power way to do so. You would not use this service to create navigation apps or apps that rely on regular location updates.

To begin the delivery of visit-related events, assign a delegate to the location manager object and call its startMonitoringVisits() method. As the location manager generates visit events, it delivers that information to its delegate’s locationManager(_:didVisit:) method. The event data delivered to your delegate includes only the information that occurred after you started the delivery of events. In other words, if you start the delivery of events after the user arrived at an interesting location, the event delivered by the system when the user departed that location would not reflect the actual arrival time. If the system terminates your app, this service relaunches it when new visit events are ready to be delivered.

Using Location Services in the Background

Most location services are meant to be used while your app is in the foreground but some can also run in the background. In some cases, location events can even cause your app to be relaunched to process an event. To run most location services in the background, you need to enable the location updates background mode in the Capabilities tab of your Xcode project. For services that launch your app, you need to request (and be granted) “Always” authorization from the user.

  • The standard location service delivers events normally while an app is running in the foreground. When your app is in the background, this service delivers events only when the location-updates background mode is enabled for the app. This service does not relaunch iOS apps that have been terminated.

  • The significant location change service delivers events normally while an app is running in the foreground or background. For a terminated iOS app, this service relaunches the app to deliver events. Use of this service requires “Always” authorization from the user.

  • The region monitoring service delivers events normally while an app is running in the foreground or background. (You can use this service for both geographic and beacon regions.) For a terminated iOS app, this service relaunches the app to deliver events. Use of this service requires “Always” authorization from the user.

  • Beacon ranging delivers events normally while an app is running in the foreground. When your app is in the background, this service delivers events only when the location-updates background mode is enabled for the app and the standard location service is running. (If the beacon region’s notifyEntryStateOnDisplay property is true, waking the device causes the app to range for beacons for a few seconds in the background.) This service does not relaunch iOS apps that have been terminated; however, you can be relaunched by monitoring beacon regions using the region monitoring service.

  • The heading service delivers events normally while an iOS app is running in the foreground. When your app is in the background, this service delivers events only when the location-updates background mode is enabled for the app and the standard location service is running. This service does not relaunch iOS apps that have been terminated.

  • The visit service delivers events normally while an iOS app is running in the foreground. When your app is in the background, this service delivers events only when the location-updates background mode is enabled for the app and the standard location service is running. For a terminated iOS app, this service relaunches the app to deliver events. Use of this service requires “Always” authorization from the user.

Enabling the location-updates background mode ensures that an app continues to receive location events while in the background. When the app moves to the background, the system adds the location-services indicator to the status bar to let the user know that an app is using location services. The system may still terminate the app at any time to reclaim its memory or other resources.

For services that relaunch the app, the system adds the location key to the options dictionary passed to the app delegate at launch time. When this key is present, you should restart your app’s location services right away. The options dictionary does not include information about the location event itself. You must configure a new location manager object and delegate and start your location services again to receive any pending events. In iOS 7.1 and later, services that cause an app to be relaunched do so even after the user force-quits the app. In previous versions of iOS, force-quitting an app prevented the app from being relaunched.

If your app does not need to do anything with location events right away, consider deferring location updates using the allowDeferredLocationUpdates(untilTraveled:timeout:) method. Deferring the delivery of location updates makes it easier for Core Location to preserve battery life while still delivering the location events your app needs.

Symbols

Requesting Authorization for Location Services

func requestWhenInUseAuthorization()

Requests permission to use location services while the app is in the foreground.

func requestAlwaysAuthorization()

Requests permission to use location services whenever the app is running.

Determining the Availability of Services

class func authorizationStatus()

Returns the app’s authorization status for using location services.

class func locationServicesEnabled()

Returns a Boolean value indicating whether location services are enabled on the device.

class func deferredLocationUpdatesAvailable()

Returns a Boolean value indicating whether the device supports deferred location updates.

class func significantLocationChangeMonitoringAvailable()

Returns a Boolean value indicating whether significant location change tracking is available.

class func headingAvailable()

Returns a Boolean value indicating whether the location manager is able to generate heading-related events.

class func isMonitoringAvailable(for: AnyClass)

Returns a Boolean indicating whether the device supports region monitoring using the specified class.

class func isRangingAvailable()

Returns a Boolean indicating whether the device supports ranging of Bluetooth beacons.

Accessing the Delegate

var delegate: CLLocationManagerDelegate?

The delegate object to receive update events.

Initiating Standard Location Updates

func startUpdatingLocation()

Starts the generation of updates that report the user’s current location.

func stopUpdatingLocation()

Stops the generation of location updates.

func requestLocation()

Request the one-time delivery of the user’s current location.

var pausesLocationUpdatesAutomatically: Bool

A Boolean value indicating whether the location manager object may pause location updates.

var allowsBackgroundLocationUpdates: Bool

A Boolean value indicating whether the app wants to receive location updates when suspended.

var distanceFilter: CLLocationDistance

The minimum distance (measured in meters) a device must move horizontally before an update event is generated.

var desiredAccuracy: CLLocationAccuracy

The accuracy of the location data.

var activityType: CLActivityType

The type of user activity associated with the location updates.

Initiating Significant Location Updates

func startMonitoringSignificantLocationChanges()

Starts the generation of updates based on significant location changes.

func stopMonitoringSignificantLocationChanges()

Stops the delivery of location events based on significant location changes.

Initiating Heading Updates

func startUpdatingHeading()

Starts the generation of updates that report the user’s current heading.

func stopUpdatingHeading()

Stops the generation of heading updates.

func dismissHeadingCalibrationDisplay()

Dismisses the heading calibration view from the screen immediately.

var headingFilter: CLLocationDegrees

The minimum angular change (measured in degrees) required to generate new heading events.

var headingOrientation: CLDeviceOrientation

The device orientation to use when computing heading values.

Initiating Region Monitoring

func startMonitoring(for: CLRegion)

Starts monitoring the specified region.

func stopMonitoring(for: CLRegion)

Stops monitoring the specified region.

var monitoredRegions: Set<CLRegion>

The set of shared regions monitored by all location manager objects.

var maximumRegionMonitoringDistance: CLLocationDistance

The largest boundary distance that can be assigned to a region.

Initiating Beacon Ranging Requests

func startRangingBeacons(in: CLBeaconRegion)

Starts the delivery of notifications for beacons in the specified region.

func stopRangingBeacons(in: CLBeaconRegion)

Stops the delivery of notifications for the specified beacon region.

func requestState(for: CLRegion)

Retrieves the state of a region asynchronously.

var rangedRegions: Set<CLRegion>

The set of regions currently being tracked using ranging.

Initiating Visit Event Updates

func startMonitoringVisits()

Starts the generation of visit-related events.

func stopMonitoringVisits()

Stops the delivery of visit-related events.

Deferring Location Updates

func allowDeferredLocationUpdates(untilTraveled: CLLocationDistance, timeout: TimeInterval)

Asks the location manager to defer the delivery of location updates until the specified criteria are met.

func disallowDeferredLocationUpdates()

Cancels the deferral of location updates for this app.

Getting Recently Retrieved Data

var location: CLLocation?

The most recently retrieved user location.

var heading: CLHeading?

The most recently reported heading.

Constants

CLAuthorizationStatus

These constants indicate whether the app is authorized to use location services.

Deferred Update Constants

Constants for specifying maximum values during deferred updates.

CLActivityType

These constants indicate the type of activity associated with location updates.

Instance Properties

Relationships

Inherits From

Conforms To