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.
- iOS 2.0+
- macOS 10.6+
- tvOS 2.0+
- watchOS 2.0+
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:
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.
Create an instance of the
CLLocationManagerclass 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.
Configure any additional properties relevant to the desired service.
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
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:
authorizationStatus()class method to get the current authorization status for your app.
CLLocationManagerobject and assign a delegate to it.
Store a strong reference to your location manager somewhere in your app.
Depending on the services you need, call one or more of the following methods:
If you use the standard location service, call the
If you use the significant location-change service, call the
If you use heading information, call the
If you monitor geographic or beacon regions, call the
If you perform ranging on Bluetooth beacons, call the
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
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
distanceFilter properties of the location manager and then call the
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
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.
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
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.