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 authorization 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.
To see the latest updates on MapKit with SwiftUI check our article highlighting the updates made on WWDC in 2023.