iOS Location Service
This post talks about the basic for ios location service. How to setup the CLLocationManager to get user's current location? For Xcode 8.1, Swift 3.0
iOS Location Service
I created this notes when I am implementing the navigation app for Mapsted. In any case we should fetch as less as location data possible to avoid battery drain so avoid getting location data constantly if possible.
Link Framework and Service Info Plist
First step is to link the necessary framework and editing the info.plist to indicate the location access of the app.
CoreLocation.framework link the framework and import the header file #import <CoreLocation/CoreLocation.h>. I will do it in a bridge header since I am using the swift.
For plist, first is the new privacy request message required by iOS 10.0 Privacy - Location Always Usage Description or Privacy - Location When In Use Usage Description you can choose for what you need depending on how you want to use the location service. Then I need to editing the Required device capabilities array. Include location-services string if I want location service in general, and gps string if I want to use the gps hardware to provides accuracy.
Getting User’s Location Data
Depending how you want to use the location data, you should always think how frequent are you going to get the data information. Try to make it as less as possible. There are two service available that gives you the user's current location. standard location service and significant-change location
The standard location service is a configurable, general-purpose solution for getting location data and tracking location changes for the specified level of accuracy.
The significant-change location service delivers updates only when there has been a significant change in the device’s location, such as 500 meters or more.
Is Location Service Available?
1 | /* This seems not correct?? |
Update
Here is an update on CLLocationManager.locationServiceEnabled(). The above commented text are taken from the apple documentation, but when I use CLLocationManager.locationServiceEnabled(), it always returns true, not matter I enabled the location service or not. Here is some questions with the same problem. 1
So now the question becomes how do I check if user has enabled the location service or not? This is what I use. CLLocationManager.authorizationStatus() == CLAuthorizationStatus.denied.
Also, we should always handle errors catches in locationManager:didFailWithError
How to request for permission?
First, remember to set the info.plist like this. Then request for permission depends on what you need. self.locationManager.requestWhenInUseAuthorization, self.locationManager.requestAlwaysAuthorization.
It seems that when we manually request permission for locations, the request only works for the first time. If user disabled the location service, we need to capture using CLLocationManager.locationServiceEnabled() and pop up the alertView ourselves
Start Standard Location Change
First create a location manager and store it inside the class property. If the location manager is already created, then we can reuse it.
Assign a delegate to update the result when user changes its location.
Setup the desiredAccuracy and distanceFilter to increase or decrease the frequency to fire the location change notification.
After everything all set, call locationManager.startUpdatingLocation() to start monitoring the location change in the background.
Below is the code I use to start a location service:
1 | let locationService = CLLocationManager() |
Handle the response
Adapt self to CLLocationManagerDelegate and implement the following method. Note that sometimes location manager will cache the old value result, so you should check if this is a recent update. Only accept a result that is not cached by comparing the location service time stamp. See code blow for details.
1 | func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { |
