Tutorial: Using SwiftUI’s LocationButton to get user’s current location in a Form
After admittedly spending quite a bit longer than anticipated, I finally got the new location button working on an app I’m working on. With iOS15, Apple introduced LocationButton, a SwiftUI view that gives your app access to your user’s location once through the CoreLocation API.
This post aims to give those who are not aiming to use the button on a map via its coordinates (which seems to be the main use case in present tutorials) but in a form with real street names. LocationButton is a great component to take advantage of, it will enhance the user’s experience with a simple click of a button to input their location as opposed to typing it. This tutorial will show you how to geocode the place name from its respective longitude and latitude coordinates.
Right, let’s get straight into it. First, you want to create a new form in SwiftUI like I’ve done in the example code below. We can achieve this using the Form object. For the sake of demonstration purposes, we’re going to give it one section where we’ll place the LocationButton. As not everyone may give permission for your app to use their permission, we want to make it as accessible as possible. Therefore, I add a TextField into the form field. We give this some relevant placeholder text and pass a binding property so the user can type their address if it is the preferred option. The CurrentLocationButton is something we now need to create ourselves.
Next up, we create the CurrentLocationButton. This is where we’ll make use of the LocationButton API. We get access to this object by importing the CoreLocationUI framework and just need to call LocationButton(.currentLocation) in the body of the view. If you’re using UIKit, you’ll want CLLocationButton.
This allows us to see the button on our screens, but that’s as far as it goes.
To request the user’s information we need to create a location manager and import the CoreLocation framework. We want to make the manager subclass from CLLocationManagerDelegate so we can handle updating locations and errors. You will need both of these else you’ll get compile errors.
Create a function like lookUpCurrentLocation to reverse geocode the location. Here you can access a number of different places such as the country, postal code and locality. Just call placemarks[0]. somewhere in that function to see the drop down of properties that are accessible in XCode. Pass those into the completion handler when there are no errors.
If you’re not after place names and coordinates are your thing, you can access these through the CLLocationManager property we’ve created at the top of the file by simply calling manager.location.coordinate.longitute. Instead of calling our reverse geocoder, you could create a property longitude in place of our place one and assign the above example to it in didUpdateLocations.
To make this nicer, we could probably add an Alert in the didFailWithError if one was to occur when requesting the user’s location.
N.B. The framework we use in the CurrentLocationButton object (CoreLocationUI) is different to the one in the manager.
Now let’s go back into the CurrentLocationButton and pass through the place name from the manager. Call the requestLocation function in the LocationButton’s body. This will go into the manager and do all that magic we’ve just set up when you tap on the button to request, you got it, the user’s current location — but only once!
Run the simulator and there we have it, text that horizontally appears next to the location button.
FYI: The simulator uses default locations such as Apple’s address. You can customise it with your own coordinates to test it works properly by clicking Features -> Location -> Customise on the Simulator.
Now we’ve got the most difficult part of the tutorial out of the way, we can go on to making the button prettier. What’s with those sharp corners on the standard location button we get from the API 😬. There are only a few properties we need to call from the API to touch it up. The most important one to me is the label style. This allows us to show the text and icon together, or one of either. As we’re dealing with a form, it feels right to just use the icon here as it doesn’t take up too much of the field’s space. The second most important one to me is the corner radius to soften up the edges.
There is much more we can do to improve this feature. We could replace the placeholder text with the text that comes from the LocationButton, but for the sake of this tutorial, I’ve kept it short. Also, my manager is very simple. We would probably also want to handle the permissions dialogue a little nicer here in a real-world app. As we only request the location once, this dialogue appears only once the first time. If the user taps ‘Don’t allow’, they will have to go into Settings to change that which kind of makes this a one-shot.
And that’s the end of this tutorial, I hope it was helpful. Do comment any suggestions or questions if they arise.