An introduction to ARKit 2 — World Mapping
As per the series, the second part is introducing World Mapping in ARKit 2. The rest of the series is as follows:
The Basics
World Mapping is an amazing new feature in ARKit 2 that allows users to save and load in environments that they have saved in previous AR experiences.
For example, you can move around a table in your backyard, capturing as much as possible, and then place a bowl of fruit in the middle of the table. Later on during the day, you can re-open the app to the same table. Automatically, the app will detect that its the same table that you previously saved and re-load your previous scene — which in this case was with a bowl of fruit on the table.
Physical 3D Mapping
With ARKit 2, your app will essentially be able to map your physical space in 3D. By moving around an object, such as the table above, you will give your app multiple perspectives of the same physical environment. These perspectives are commonly referred to as anchors.
Feature Points
With world mapping, your device will also scan many feature points that will be used to identify the space another time. These features can reside on planes, corners, points, or just random areas of interest that are unique.
AR World Mapping allows for two new capabilities:
Sharing Experiences
World mapping in ARKit allows you to share your map with another device, such as another iPad or iPhone that also has ARKit 2 (iOS 12 or above). With that, you can interact in real-time and experience the same thing — then come back to it another time. You could also build networked experience and interact at the same time in things such as games. An example Apple demoed (and is open-source) is SwiftShot. You can download it here.
Persistent AR Experiences
This allows you to save a world map before you close your app, then load it the next time you open it. If opened in the same physical space that you saved it in, your virtual experience will continue. An example use case would be loading and saving a board on your wall or on your table that has a list of stuff you need to remember (pretty tedious example, but whatever). Every time you open the app near your desk or on the same place with that board, it will load back in as if you never left.
Using World Mapping in your App
The main method you need to use to instantiate and use a world map is getCurrentWorldMap(completionHandler:)
. This allows you to save a session’s world map. Then, you can assign it to a configuration’s initialWorldMap
property and use run(_:options:)
to start another session with the same anchors and physical world map.
Retrieving a world map from the session object
session.getCurrentWorldMap{ worldMap, error in
guard let worldMap = worldMap else {
showAlert(error)
return
} return worldMap
}
Load world map and run the configuration
let configuration = ARWorldTrackingConfiguration()
configuration.initialWorldMap = worldMap
session.run(configuration)
Saving/Archiving World Map Data for Persistence
To save a world map (usually in thegetCurrentWorldMap(completionHandler:)
handler), you would use the following method to archive it locally, using NSKeyedArchiver:
func saveWorldMap(_ worldMap: ARWorldMap, to url: URL) throws {
let data = try NSKeyedArchiver.archivedData(withRootObject: worldMap, requiringSecureCoding: true)
try data.write(to: url)
}
Load a Previously Saved World Map
A good thing to do in your app is to try to retrieve a world map before trying to get the current world map or saving it.
func loadWorldMap(from url: URL) throws -> ARWorldMap {
let mapData = try Data(contentsOf: url)
guard let worldMap = try NSKeyedUnarchiver.unarchivedObject(of: ARWorldMap.classForKeyedUnarchiver(), from: mapData) as? ARWorldMap
else { throw ARError(.invalidWorldMap) }
return worldMap
}
Generally, a good flow to follow for your app’s launch is:
- Try loading in a world map with the
loadWorldMap
method - If no world map is found, prompt the user to move around the room so the app can get a world map, using the
getCurrentWorldMap
method. - Once a world map has been retrieved, save it using the
saveWorldMap
method.
That’s it! Just like that you have created a world mapping system in your app with ARKit. It’ll be really cool to see how developers apply it to their own apps.