Getting Started

First off, you can check out this sample repository I used to test out and showcase our little AR adventure. It provides a simple app using only ARKit to place an object in your AR scene, and it also has our complex sample of POI navigation in an AR scene. Included bugs are to be considered features. 🤓

You are going to need Xcode 9 and iOS 11, which are the minimum requirements for working with ARKit and SceneKit. However, keep in mind that all of the code snippets in this article were made using Xcode 10 and iOS 12 ⚠️, since ARKit’s newest features aren’t available for previous installments and I wanted to be on the forefront of it all.

The focus of this article isn’t really about guiding you through setting up and coding the AR project itself. If you need help setting up an AR project from scratch, I’m going to refer you to this wonderful set of articles. If you’re still going for the “pseudo-code-along”, have updated your development environment, and set up an AR project, then the fun part is about to begin. 🤓

Points of Interest

If you recall our initial analysis, we intend to use CoreLocation and MapKit for the GPS, POIs, and routing; and this AR app obviously needs ARKit and SceneKit for the AR part. 😜 But before we do any fancy stuff with AR, we’re going to need some data to work with, a.k.a, the POIs around the user’s current location.

It’s coming, I promise. 😅

To get started, all we have to do is import CoreLocation into our project, next we need to set up a LocationManager that will continuously feed us the user’s GPS location. For the purpose of our app, and since AR will already be draining the battery, I’ve decided to go with an accuracy that should be good enough for walking around, but feel free to try out other accuracies.

And once we have the user’s location, we can just issue a query for nearby POIs using MapKit. I’ve chosen to only include locations within 2 Km of the user’s current location, which should include anything within walking distance.

We now have nearby POIs and can go back to the “Augmented Reality” part of our app. This is about half of our Intellectual Property’s value in only a handful of lines!

AR & GPS

After digging a bit around in this awesome collection of iOS AR resources, I found a couple of promising projects that might help us with AR and our POI’s GPS locations:

After giving them all a try, I decided to opt for ARCL as it offers a really clean and easy to use out-of-the-box experience for setting up a GPS aware AR scene. What I mean by this last part is that objects placed in our AR scene respect their real-world GPS positions and distances. I can already hear some of you thinking to yourselves “why didn’t he just build this from scratch?”. Well, I encourage you to think of the problem at hands and its inevitable complexity:

Once you have the POIs near the user’s current location, where do you place them in your AR scene?

Unfortunately, your AR scene’s reference planes don’t match up with the ones used by GPS coordinates out-of-the-box 😞 How do you align them? Do you use the phone’s compass and your current location as the point of reference? What’s more, your AR scene’s “ground” plane appears to be perfectly flat, which might work for small distances between locations, but won’t accurately depict an object’s position over greater distances due to the Earth’s curvature 🌍 (unless you believe the Earth is flat 🤪). As you can see, it’s not an easy challenge to tackle head-on and in order to cut some unnecessarily hard corners: ARCL to the rescue!

Full disclosure: the curvature of the Earth wasn’t going to affect our app in any visible way, as we’ll be dealing with “small” distances of at most 2 Km, but by thinking about potential problems and opting to use ARCL as a mitigator we’re already making a sturdier application. 😉

AR POI Scene

As with our first AR scene, it also doesn’t take much to add our recently acquired POIs using the ARCL framework. We’re going take a page from their book and create a custom node that extends LocationNode (which in turn extends SCNNode): our very own LocationTextAnnotationNode.

A LocationTextAnnotationNode is comprised of a text child node, used to display the name of the POI and it’s relative distance to our current position; and an image node, which we use to visually locate the POI in the AR scene. As you can see, the majority of the code itself is about how each node should be presented aesthetically, with little thought being poured into how it will all fall into place within the AR scene… 🤔 Thanks to ARCL doing the heavy lifting!

After being created, each LocationTextAnnotationNode is then added to the AR scene. Pretty simple, right?

POI Routing

Now that the POIs have been properly placed in our AR scene, we want to be able to interact with them, enabling us to select a destination and ask for walking directions to it. Setting up the tap gesture recognizer isn’t too troublesome, we just need to hit-test the tapped location in our AR scene, retrieving all affected scene nodes, and we just pick the first eligible match.

Having selected a POI, we want to ask for directions from our current location to its GPS coordinates, which we will be addressing as a contiguous bundle of route segments, and finally translate those directions into scene nodes we can add to our AR scene.