Augmented Reality iOS Tutorial: Location Based
In this augmented reality tutorial, you’ll learn how to use your iOS users location to create compelling augmented reality experiences. By Jean-Pierre Distler.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Augmented Reality iOS Tutorial: Location Based
30 mins
Augmented reality is a cool and popular technique where you view the world through a device (like your iPhone camera, or Microsoft HoloLens), and the device overlays extra information on top of the real-world view.
I’m sure you’ve seen marker tracking iOS apps where you point the camera at a marker and a 3D model pops out.
In this augmented reality iOS tutorial, you will write an app that takes the user’s current position and identifies nearby points of interest (we’ll call these POIs). You’ll add these points to a MapView
and display them also as overlays on a camera view.
To find the POIs, you’ll use Google’s Places API, and you’ll use the HDAugmentedReality
library to show the POIs on the camera view and calculate the distance from the user’s current position.
This tutorial assumes you have some basic familiarity with MapKit. If you are completely new to MapKit, check out our Introduction to MapKit tutorial.
Getting Started
First download the starter project and make yourself familiar with the content. Select the Places project in the project navigator, the Places target in the editing pane, and in the General tab, within the Signing section, set Team to your developer account. Now you should be able to compile the project. The Main.storyboard contains a Scene with a MapView and a UIButton already hooked up for you. The HDAugmentedReality
library is included and there are files PlacesLoader.swift and Place.swift. You use them later to query a list of POIs from Googles Places API and map the result into a handy class.
Before you can do anything else, you need to obtain the user’s current location. For this, you’ll use a CLLocationManager
. Open ViewController.swift and add a property to ViewController
below the mapView
outlet and call it locationManager
.
fileprivate let locationManager = CLLocationManager()
This just initializes the property with a CLLocationManager
object.
Next add the following class extension to ViewController.swift.
extension ViewController: CLLocationManagerDelegate {
}
Before you can get the current location you have to add a key to the Info.plist. Open the file and add the key NSLocationWhenInUseUsageDescription with a value of Needed for AR. The first time you try to access location services iOS shows an alert with this message asking the user for the permission.
Now that everything is prepared, you can get the location. To do this, open ViewController.swift and replace viewDidLoad()
with the following:
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
locationManager.requestWhenInUseAuthorization()
}
This is a basic configuration for the locationManager
. The manager needs a delegate to notify when it has updated the position of the iDevice. You set it to your view controller using self
. Then the manager needs to know how accurate the position should be. You set it to kCLLocationAccuracyNearestTenMeters
, which will be accurate enough for this example project. The last line starts the manager and asks the user to grant permission to access location services if it was not already granted or denied.
Note: For desiredAccuracy
, you should use the lowest accuracy that is good enough for your purposes. Why?
Say you only need an accuracy of some hundred meters – then the LocationManager
can use phone cells and WLANs to get the position. This saves battery life, which you know is a big limiting factor on iDevices. But if you need a better determination of the position, the LocationManager
will use GPS, which drains the battery very fast. This is also why you should stop updating the position as soon as you have an acceptable value.
Note: For desiredAccuracy
, you should use the lowest accuracy that is good enough for your purposes. Why?
Say you only need an accuracy of some hundred meters – then the LocationManager
can use phone cells and WLANs to get the position. This saves battery life, which you know is a big limiting factor on iDevices. But if you need a better determination of the position, the LocationManager
will use GPS, which drains the battery very fast. This is also why you should stop updating the position as soon as you have an acceptable value.
Now you need to implement a delegate method to get the current location. Add the following code to the CLLocationManagerDelegate
extension in ViewController.swift:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//1
if locations.count > 0 {
let location = locations.last!
print("Accuracy: \(location.horizontalAccuracy)")
//2
if location.horizontalAccuracy < 100 {
//3
manager.stopUpdatingLocation()
let span = MKCoordinateSpan(latitudeDelta: 0.014, longitudeDelta: 0.014)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.region = region
// More code later...
}
}
}
Walking through this method step-by-step:
- Every time the
LocationManager
updates the location, it sends this message to its delegate, giving it the updated locations. The locations array contains all locations in chronological order, so the newest location is the last object in the array. First you check if there are any locations in the array and if there is at least one you take the newest. The next line gets the horizontal accuracy and logs it to the console. This value is a radius around the current location. If you have a value of 50, it means that the real location can be in a circle with a radius of 50 meters around the position stored inlocation
. - The
if
statement checks if the accuracy is high enough for your purposes. 100 meters is good enough for this example and you don't have to wait too long to achieve this accuracy. In a real app, you would probably want an accuracy of 10 meters or less, but in this case it could take a few minutes to achieve that accuracy (GPS tracking takes time). - The first line stops updating the location to save battery life. The next three lines zoom the
mapView
to the location.
Build and run on your device, and keep your eyes on the console to see how the locations come in and how the accuracy gets better and better. Eventually you'll see the map zoom to an area centered on your current location.
verticalAccuracy
that is the same as horizontalAccuracy
, except that it’s for the altitude of the position. So a value of 50 means that the real altitude can be 50 meters higher or lower. For both properties, negative values are invalid.