Updating the User’s Location with Core Location and Swift Concurrency in SwiftUI
Learn how to create an asynchronous API to access Core Location on a SwiftUI app.
You can create your own wrappers to manage access to iOS core services, taking advantage of the features of the Swift language to create modern and flexible APIs for your application.
One of the services you can work with is Core Location, using Swift Concurrency to create a simple and elegant approach to accessing the user location. With a CheckedContinuation object, we can interface between synchronous and asynchronous code, so we can update the location of the user once the location manager can retrieve it using delegation.
Creating the Location Manager
Create a LocationManager
class that inherits from the NSObject
class and conforms to the CLLocationManagerDelegate
protocol. Add a private property called locationManager
, a CLLocationManager
object that will provide us access to the location services of the device.
Also, override the default initializer so we can assign the delegate to the locationManager
object to be the LocationManager
class.
Requesting Authorization
To be able to access the current location of the user you must ask for authorization to use the location services of the device.
On the project settings, you must go into the Info area and add to the Custom iOS Target properties the key Privacy - Location When In Use Usage Description
and a string value with a message explaining why your application needs access to the location services.
With that done, create a short method to check if the location manager's authorisation is not determined and request it if that’s the case.
Getting the Current Location
Now to get the user's current location create a property that will store an CheckedContinuation
object that, when resumed, returns an CLLocation
object or throws an error.
Create a computed property named currentLocation
that will asynchronously return the result of the continuation object once it is resolved. If everything goes well we will receive an CLLocation
object, if not an error will be thrown.
The continuation
property is set with the continuation object provided by the withCheckedThrowingContinuation(function:_:)
method in its body closure, and then we use the locationManager to request a one-time delivery of the user’s current location.
The last step is to implement the CLLocationManagerDelegate
methods that are triggered when the requestLocation()
method is called. Provide an implementation for a successful case, resuming the continuation object returning the current user’s location, and a case where it fails to provide the user’s location, resuming the continuation object by throwing the error object associated with it.
To see an example of how to use the location manager in a SwiftUI view to display the current user location on a Map check the following code snippet on GitHub.