Getting a users current location is important for many applications.
It helps provide a better user experience by localizing the app. Users can find more relevant items near them. Let’s take a look how we can solve this problem in Swift.
To get a user’s current location, you’ll first need to import MapKit
and CoreLocation
in the top of your view controller.
import MapKit
import CoreLocation
Next you’ll need to create a CLLocationManager
let locationManager = CLLocationManager()
You will have to decide whether your application will need the users location always (even when in it’s in the background) or only when the apps in use.
To request location authorization always, use this line of code:
locationManager.requestAlwaysAuthorization()
Otherwise, to request location authorization when the app is in use:
locationManager.requestWhenInUseAuthorization()
Now make sure your ViewController subclasses CLLocationManagerDelegate
:
class ViewController: UIViewController, CLLocationManagerDelegate {
...
}
We can now set our location manager to update:
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
The location manager will update the delegate function. We’ll add some code in our delgate function to print out the location:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
print("locations = \(locValue.latitude) \(locValue.longitude)")
}
Now run your application. You’ll notice in console, you’ll get some errors:
This app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain both “NSLocationAlwaysAndWhenInUseUsageDescription” and “NSLocationWhenInUseUsageDescription” keys with string values explaining to the user how the app uses this data
Not to worry, this is expected. This means we have to update our Info.plist
file. Open it up from the Project Navigator:
Right click and select Add Row
. Paste in NSLocationWhenInUseUsageDescription
into the Information Property List column of your newly added row. Set it’s type to string and then set its value to a message you’d like to display to the user.
For example, I can put “We’ll use this to personalize your app experience”. The permissions dialog will look like so:
If you’ve requested for location access always, you’ll need to do add another row for NSLocationAlwaysAndWhenInUseUsageDescription
Your Info.plist
rows should look something like this:
That’s it, you should be able to run your application and see the users location data printed into console (using our example code). The users location will be printed every time it changes.
Here’s the full example code for this article (only 23 lines of code!):
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
print("locations = \(locValue.latitude) \(locValue.longitude)")
}
}
Your console should output something like this:
locations = 37.785834 -122.406417
If you’re using the simulator, you’ll notice that the user location isn’t being updated. That’s because you need to simulate location in the iOS simulator.
Changing locations on the simulator is a great way to test features of your application, without physically having to move to different locations.
To change the location on your iOS simulator go to Debug > Location > Custom Location
Here you will be able to set the longitude and latitude to any location.
To get the longitude and latitude of a location in Google Maps, right click and select “What’s here”.
Then at the bottom of your screen, the longitude and latitude will be displayed.
To get the city and country from a longitude and latitude, we must do a reverse geo-code. In swift, it’s quite simple to do:
Here’s a function that you can copy and paste into your code:
func fetchCityAndCountry(from location: CLLocation, completion: @escaping (_ city: String?, _ country: String?, _ error: Error?) -> ()) {
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
completion(placemarks?.first?.locality,
placemarks?.first?.country,
error)
}
}
We use it in our example code like so:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location: CLLocation = manager.location else { return }
fetchCityAndCountry(from: location) { city, country, error in
guard let city = city, let country = country, error == nil else { return }
print(city + ", " + country)
}
}
Our console output is:
San Francisco, United States
The locale is a setting the user sets their iOS device to. It controls the language and other formatting options.
It can tell you what country the user is from, or at least what country their device is currently set to.
To get the current device locate, you can use the following code:
let locale = Locale.current
print(locale)
Since my device is set to English (US), this printed out:
en_US
You can view a list of locales here.
The Complete iOS App Development Bootcamp
Disclosure: This website may contain affiliate links, meaning when you click the links and make a purchase, we receive a commission.