Quickstart in iOS Swift
Integrate the ARwayKit SDK with iOS Swift
In this quickstart guide, we will be integrating the ARwayKit SDK with iOS Swift. This example will be using Unity as a Library to integrate into an iOS app.
Installed Versions
In this guide, we will be using the following versions:
Xcode: 14.3
Unity: 2022.3.29f1 LST
Download the ARwayKit SDK
Download the ARwayKit SDK project from GitHub as a ZIP. You can contact us for access to the ARwayKit SDK.
Create a Basic Project in Xcode
For this example a new iOS app called "SwiftUnity" will be created with interface "Storyboard" and language "Swift".
Generate the Build for the iOS Platform
Updating the Addressables Groups
When opening the project in Unity for the first time, you will need to build the Addressables Groups.
Switch the build platform to either iOS or Android
"File-> Build Settings..." then select the Android or iOS as the Platform.
Click "Switch Platform" on the bottom right.
Navigate to "Window -> Asset Management -> Addressable -> Groups".
In the Addressables Groups window, click on "Build -> New Build -> Default Build Script".
In the Console window, you should see the success message "Addressable content successfully built".
Building the Project
Steps
In Unity select File -> Build Settings.
Switch the Platform to iOS.
Select option "Build Project".

Export the ARwayKit Unity SDK to a new folder and name it "iOSBuild" and place it in the base directory for the iOS project.
Setup Xcode workspace
Xcode workspace allows to work on multiple projects simultaneously and combine their products
Open your Xcode project.
Create workspace and save it as both.xcworkspace. (File / New / Workspace).
All the steps are done from just created Workspace project.
Add SwiftUnity.xcodeproj and generated Unity-iPhone.xcodeproj from step #2 to workspace on a same level ( File / Add Files to “both” ).
Add UnityFramework.framework
With this step we add Unity player in the form of a framework to NativeiOSApp, it does not change the behavior of NativeiOSApp yet
Select NativeiOSApp target from NativeiOSApp project.
In "General" tab / "Frameworks, Libraries, and Embedded Content" press +.
Add Unity-iPhone/UnityFramework.framework.
In "Build Phases" tab, expand "Link Binary With Libraries".
Remove UnityFramework.framework from the list (select it and press - ).
Make Data folder to be part of the UnityFramework
By default Data folder is part of Unity-iPhone target, we change that to make everything encapsulated in one single framework file.
Change Target Membership for Data folder to UnityFramework.
Next, open Info.plist and add the following rows:
Privacy - Microphone Usage Description: Used for creating audio content
Privacy - Camera Usage Description: Used for AR Content and mapping
Privacy - Location Usage Description: Used to attach maps with global coordinates and public map searching
Privacy - Location When in Usage Description: Used to attach maps with global coordinates and public map searching
Privacy - Photo Library Usage Description: This app requires access to save media
Privacy - Photo Library Additions Usage Description: This app requires access to save media

Swift Code
To create an entry point to SwiftUI, create a new SwiftUI view called ContentView.swift and add a single button to launch ARway.
import SwiftUI
struct ContentView: View {
var body: some View {
Button(action: {
Unity.shared.show()
}) {
Text("Launch ARway!")
}
}
}
Next, update the ViewController.swift file to match the following.
import UIKit
import SwiftUI
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let vc = UIHostingController(rootView: ContentView())
addChild(vc)
vc.view.frame = self.view.frame
view.addSubview(vc.view)
vc.didMove(toParent: self)
}
}
Next, implement the connection between the Unity SDK and the Swift app. A new singleton called Unity.swift is created with the following code.
import Foundation
import UnityFramework
class Unity: UIResponder, UIApplicationDelegate {
static let shared = Unity()
private let dataBundleId = "com.unity3d.framework"
private let frameworkPath = "/Frameworks/UnityFramework.framework"
private lazy var unityFramework: UnityFramework? = {
guard let bundle = loadUnityFramework() else {
return nil
}
let ufw = bundle.principalClass?.getInstance()
ufw?.setDataBundleId(dataBundleId)
ufw?.register(self)
return ufw
}()
private var hostMainWindow: UIWindow?
private var isInitialized: Bool {
unityFramework?.appController() != nil
}
func show() {
guard isInitialized else {
initWindow()
return
}
showWindow()
}
func setHostMainWindow(_ hostMainWindow: UIWindow?) {
self.hostMainWindow = hostMainWindow
}
private func initWindow() {
guard !isInitialized else {
showWindow()
return
}
guard let unityFramework = unityFramework else {
print("ERROR: Was not able to load Unity")
return unloadWindow()
}
self.unityFramework = unityFramework
unityFramework.runEmbedded(withArgc: CommandLine.argc, argv: CommandLine.unsafeArgv, appLaunchOpts: nil)
}
private func showWindow() {
guard let unityFramework = unityFramework else {
return
}
unityFramework.showUnityWindow()
}
private func unloadWindow() {
guard let unityFramework = unityFramework else {
return
}
unityFramework.unloadApplication()
}
private func loadUnityFramework() -> Bundle? {
let bundlePath = Bundle.main.bundlePath + frameworkPath
guard let bundle = Bundle(path: bundlePath), !bundle.isLoaded else {
return nil
}
do {
try bundle.loadAndReturnError()
} catch {
print("ERROR: Failed to load Unity framework: \(error)")
return nil
}
guard unityFramework?.appController() == nil else {
return bundle
}
let machineHeader = UnsafeMutablePointer<MachHeader>.allocate(capacity: 1)
machineHeader.pointee = _mh_execute_header
unityFramework?.setExecuteHeader(machineHeader)
return bundle
}
}
extension Unity: UnityFrameworkListener {
func unityDidUnload(_ notification: Notification!) {
unityFramework?.unregisterFrameworkListener(self)
unityFramework = nil
hostMainWindow?.makeKeyAndVisible()
}
}
Next update the AppDelegate.swift file to pass the main window reference to Unity.
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Unity.shared.setHostMainWindow(window)
return true
}
}
You should now be able to build and run the project on an iOS device.
Last updated