Tutorial: Connecting Core Location to a SwiftUI App

How to connect Apple’s Core Location service to a SwiftUI App

Cole Dennis
6 min readSep 23, 2022

Project Setup

First, let’s create a new SwiftUI Xcode project. I’m using the iOS App template:

Xcode new project screen, with the iOS App template highlighted.

I’ve selected SwiftUI as the interface and Swift as the language:

New project settings in Xcode, with SwiftUI selected as the interface and Swift selected as the language.

You should now have a basic setup that looks like this:

Xcode screen when opening a new SwiftUI project from the Xcode app template.

Location Data Manager

In order to access Core Location data, we are going to set up a Location Data Manager class that will contain a CLLocationManager variable.

What is CLLocationManager?

CLLocationManager (Apple Documentation) is an object that is designed to manage Core Location based behavior. When setting this up in our project, we will do the below:

  • Set up Class containing CLLocationManager
  • Set up delegate objects confirming to CLLocationManagerDelegate protocol (Apple Documentation) that will receive updates from CLLocationManager
  • Set up a @Published variable so that our SwiftUI view will update when the status changes in our Class

Setting Up CLLocationManager In Our App

Add a new Swift file to your project:

Add new file screen in Xcode, with Swift file selected

Your new Swift file should look like this:

Empty Swift File in Xcode for the LocationDataManager class.

Import CoreLocation into this file, and add the below code:

This sets up our basic CLLocationManager object, and sets the LocationDataManager class as its delegate, so when there are updates to CLLocationManager, they will be passed along by the LocationDataManager class to our app.

If interested, I encourage you to type “locationManager” in this class and look through all the different populated items that this object can be customized to react to:

A screenshot showing all the different completion options for locationManager in Xcode

Requesting Authorization of Location Data From User

As you can probably imagine, a user’s location data is very sensitive, so we will need to request authorization from the user before we are allowed to access their location data. For the purposes of this tutorial, we will only be requesting location data “When in Use”, which means that location updates will only occur when a user is actively using our app. More on this topic can be found on this Apple Documentation site.

First, we will add a Info.plist description for the NSLocationWhenInUseUsageDescription key. This text is what will be displayed on the privacy pop up the user receives on their device when we first try to activate the Core Location.

Navigate to the Info tab on the top level of the Xcode navigation:

The info tab showing the Info.plist information for our app.

Add a new item with the “Privacy — Location When In Use Usage Description” key:

Adding in the “Privacy — Location When In Use Usage Description” key into the Info.plist file

Add a string on the right side — this is what will appear on the iOS alert pop up:

Adding a string as the value for our “Privacy — Location When In Use Usage Description” key

Now we are ready to make the authorization request. We will be adding a function to our LocationDataManager delegate that will handle the different outcomes of authorization requests (authorized, not authorized, or not yet determined.

Add this function to your code:

Requesting the Location Data from Core Data

Now that we have the authorization request in place, we are ready to actually request the data from Core Data. The location data you need will depend on your use case. If you need the most precise and regular location data, you would want to call the startUpdatingLocation() function, however, note that this is the most power-consuming option. Other options, such as startMonitoringSignificantLocationChanges() and startMonitoringVisits() are lower power, but also not as precise or as frequently updated. For our tutorial, I’ll be adding the requestLocation() call, which gets a single, one time location data point. More information on these different options can be found on the Apple Documentation site.

Add the below call to the .authorizedWhenInUse result in the .authorizationStatus switch to call it when our authorization is approved.

manager.requestLocation()

We will also need to tell our LocationDataManager class to conform to ObservableObject in order to link it up with our SwiftUI view, so that updates to the Core Location data propagate updates across our app.

Your LocationDataManager should now look like this:

In our ContentView, we will want the SwiftUI view to update when .authorizationStatus changes. This way, our app will update when the authorization is received. In order to update our SwiftUI view, I’m going to add a new @Published variable and add updates in the .authorizationStatus switch statement.

First, add this to the LocationDataManager class:

@Published var authorizationStatus: CLAuthorizationStatus?

Then, for each of the switch statement cases, set the new “authorizationStatus” variable like this:

case .authorizedWhenInUse:  // Location services are available.authorizationStatus = .authorizedWhenInUselocationManager.requestLocation()break

When you add this throughout the switch statement, it should look like this:

We need to add in 2 more delegate functions to our Class that inherit from the CLLocationManagerDelegate protocol before we can move on to the UI. We will not be fully exploring these in the scope of this tutorial, but I do want to briefly touch on them as they are required to not have errors at build time:

locationManager(_:didUpdateLocations:) — Apple Documentation

This is an instance method that will tell our delegate that new location data is available. Add this to the LocationDataManagerClass:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {// Insert code to handle location updates}

locationManager(_:didFailWithError:) — Apple Documentation

This is an instance method that would update our delegate if the location manager was unable to retrieve location data. For the purposes of our tutorial, we will be printing this error if one arises:

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {print("error: \(error.localizedDescription)")}

The final LocationDataManager Class should look like this:

Connecting the Location Data to a SwiftUI View

Now that we have set up our call to get the Core Location data, we need to connect it to our SwiftUI view.

First, we need to add in a new @StateObject instance of our LocationDataManager class, so that we can access the LocationDataManger data.

@StateObject var locationDataManager = LocationDataManager()

You can learn more about @StateObject and find the right solution for your App with this helpful Hacking With Swift article.

To help us visualize what’s happening, I’m going to reuse the switch statement from our LocationDataManger, but use SwiftUI text views. To access the location data, we can call our locationManager variable within the LocationDataManager class, and access its .location property, which is the most recently retrieved user location, in the form of a CLLocation item. From here, you can access the coordinate data, and then the latitude and longitude description data (so that it’s in the form of a string for our text view). These items could return empty, so I’ve added “Error loading” strings as a fall back:

Text("Latitude: \(locationDataManager.locationManager.location?.coordinate.latitude.description ?? "Error loading")")Text("Longitude: \(locationDataManager.locationManager.location?.coordinate.longitude.description ?? "Error loading")")

Your updated ContentView should look something like this:

Run your app, and you should see a pop up to use your location. I’ve selected “Allow While Using App”, and as you can see in the below screenshots (which have been blurred), it works! The SwiftUI views are being updated based on the Core Location data!

3 Screenshots showing the app running on a device. The first screenshot shows the location privacy pop up, the second screenshot shows the “Finding your location” text, and the third screenshot shows the CoreLocation working (but the details have been blurred out for privacy reasons).

I hope that this tutorial was helpful, and can get you started on your Core Location and SwiftUI journey!

Here’s the full repository for this tutorial on GitHub for easy access:

Here’s some additional Apple Documentation links that might be helpful:

Core Location

Getting the Current Location of a Device

Configuring Your App To Use Location Services

CLLocationAccuracy: The Accuracy of a Geographical Coordinate

distanceFilter — The Minimum Distance in Meters the Device Must Move Horizontally Before an Update Event is Generated.

--

--

Responses (4)