Get user’s location on iOS with Swift

Reading Time: 4 minutes

In this simple tutorial we’re going to cover how to get user’s location on iOS with Swift. iOS has a pretty powerful API for working with maps and tracking user locations.

To use these features we need to import CoreLocation framework. CoreLocation framework provides services for determining a geographic location, altitude, orientation, etc. The framework uses available hardware (Wi-Fi, GPS, Bluetooth, magnetometer, barometer) so be careful with tracking because tracking user’s location all the time can drain a battery really fast.

If you want to know more about CoreLocation you can find more information in Apple’s official documentation available here – https://developer.apple.com/documentation/corelocation.

Note – in this post we’re not going to cover how to use map and show location on map but only how to fetch user location. I’ll leave that for some other post in the future.

So let’s start.

 

Setup Xcode project

Before learning how to fetch user’s location let’s setup couple of things. First, open Xcode and create a new project. After this we need to add couple of values in our Info.plist file, otherwise fetching user’s location won’t wok. This is because users needs to give us permission to track their location. To do this select your project target, click on “Info” tab and add following values:

•         key “Privacy – Location When In Use Usage Description” – needed to fetch user location; for value put description that will explain to your users why do you need to access their location

•         key “Privacy – Location Usage Description” – also needed to fetch user location; for value put description that will explain to your users why do you need to access their location

Note that you can track user location while he/she is using the app or always (even when your application is in the background). In this post we’re covering how to fetch user location while app is in the foreground. If you want to track location all the time add keys “Privacy – Location Always Usage Description” and “Privacy – Location Always and When In Use Usage Description”. The first time user opens application and you want to fetch location app will request authorization by displaying alert with message you put in Info.plist. The system records the user’s response and does not display this alert upon subsequent requests.

get user location ios swift

 

How to fetch user’s location

Now that we’re done with project setup let’s write some code.

Create new class and name it something like “GeolocationService”. You want to handle fetching user location in some reusable class so that you can use this feature on multiple places and not copy paste code in every view controller where you need this feature.

Put following line on top of your class:

import CoreLocation

Now to get user location we need to use CLLocationManager, an object that you use to start and stop the delivery of location-related events to your app.  You use instance of this class to configure, start, and stop the Core Location services. More information about CLLocationManager can be found here.

let locationManager = CLLocationManager()

Note – we need to store a strong reference to CLLocationManager and it is required until all tasks involving that object are complete because most location manager tasks run asynchronously.

Our class also needs to conform to CLLocationManagerDelegate protocol so that we can receive location information once CLLocationManager fetches user location. We also need a way to notify interested view controllers once user location is fetched so add GeolocationServiceDelegate protocol on top of our class and define following methods:

protocol GeolocationServiceDelegate {
    func didFetchCurrentLocation(_ location: GeoLocation)
    func fetchCurrentLocationFailed(error: Error)
}

In case of an error we’re going to call fetchCurrentLocationFailed method and pass Error object. In case user location is successfully fetched we’re going to call didFetchCurrentLocation and pass our location (GeoLocation object). GeoLocation is a simple model that has only 2 properties – latitude and longitude:

struct GeoLocation {
    var latitude: Double
    var longitude: Double
}

Your “GeolocationService” class should look like this:

import UIKit
import CoreLocation

protocol GeolocationServiceDelegate {
    func didFetchCurrentLocation(_ location: GeoLocation)
    func fetchCurrentLocationFailed(error: Error)
}

class GeolocationService: NSObject {
    let locationManager = CLLocationManager()
    var delegate: GeolocationServiceDelegate

    init(delegate: GeolocationServiceDelegate) {
        self.delegate = delegate
        super.init()
        self.setupLocationManager()
    }

    private func setupLocationManager() {
        if canUseLocationManager() {
           locationManager.delegate = self
           locationManager.desiredAccuracy = kCLLocationAccuracyBest
           locationManager.requestWhenInUseAuthorization()
           locationManager.requestLocation()
           //            locationManager.startUpdatingLocation()
        }
    }

    private func canUseLocationManager() -> Bool {
        return CLLocationManager.locationServicesEnabled()
    }

    deinit {
        locationManager.stopUpdatingLocation()
    }
}

extension GeolocationService: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let location = locations.last {
            let geoLocation = GeoLocation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
            delegate.didFetchCurrentLocation(geoLocation)
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        delegate.fetchCurrentLocationFailed(error: error)
    }
}

In our init method we’re setting GeolocationServiceDelegate and after that we’re going to setup location manager. First we need to check can we use location manager by calling CLLocationManager.locationServicesEnabled(). In case we have a permission to use it we’re doing a setup of a location manager.

locationManager.delegate = self            
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()

First we’re setting our class as a location manager delegate and desired accuracy. After that we need to tell location manager do we want to use it all the time or only when app is in the foreground.

If you want to fetch user location only once then call method requestLocation() on our location manager. In case you want updates of user’s location call method startUpdatingLocation() – note that you’ll receive user’s location until you call method stopUpdatingLocation().

locationManager.requestLocation()
//            locationManager.startUpdatingLocation()

In case user’s location was successfully fetched, didUpdateLocations (of CLLocationManagerDelegate) will fire giving you current location. In case fetching a user location failed didFailWithError will be called giving you exact error.

 

Wrap up

So as you see fetching user’s location on iOS is pretty simple. In some of the future posts I’ll try to cover how to convert coordinates into address (process called geocoding) or show location on a map.

I hope this article was helpful and useful and that you learned something. If it was please share this article with your friends. And if you have any questions or problems leave me a comment or send an email.

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *