# Quickstart in 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](https://github.com/Unity-Technologies/uaal-example/blob/uaal-example/19LTS-21LTS/docs/ios.md) 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](https://www.arway.ai/contact) 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

{% hint style="info" %}
Make sure to add the Account ID and Secret Key variables to the Unity project. Follow the guide for [Building from the Source Code](https://docs.arway.ai/arway-sdk/building-from-the-source-code) for instructions.
{% endhint %}

### **Updating the** Addressables Groups

When opening the project in Unity for the first time, you will need to build the Addressables Groups.

1. Switch the build platform to either iOS or Android
   * "File-> Build Settings..." then select the Android or iOS as the Platform.
2. Click "Switch Platform" on the bottom right.
3. Navigate to "Window -> Asset Management -> Addressable -> Groups".
4. In the Addressables Groups window, click on "Build -> New Build -> Default Build Script".
5. In the Console window, you should see the success message "Addressable content successfully built".

{% hint style="info" %}
When making any changes that affect localization strings, you will need to update the Addressables Groups.
{% endhint %}

### **Building the Project**

**Steps**

1. In Unity select File -> Build Settings.
2. Switch the Platform to iOS.
3. Select option "Build Project".

<figure><img src="https://4128853559-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlDytDSBRx8P4ZZXD57DA%2Fuploads%2Fkv1z9m0uJ74kR9QClr7W%2FScreenshot%202023-05-01%20at%208.03.51%20PM.png?alt=media&#x26;token=69151532-10b5-455c-bd32-b0ab6fa834b9" alt=""><figcaption><p>Build the project, this example will run it as debug.</p></figcaption></figure>

4. 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

1. Open your Xcode project.
2. Create workspace and save it as both.xcworkspace. (File / New / Workspace).\
   ![](https://4128853559-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlDytDSBRx8P4ZZXD57DA%2Fuploads%2F6DdvYdX3x59dbDE60TPD%2FScreenshot%202023-05-05%20at%209.23.05%20PM.png?alt=media\&token=6401413a-5359-4e8d-9bb6-dafa1706e6be)
3. All the steps are done from just created Workspace project.
4. Add SwiftUnity.xcodeproj and generated Unity-iPhone.xcodeproj from step #2 to workspace on a same level ( File / Add Files to “both” ).\
   ![](https://4128853559-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlDytDSBRx8P4ZZXD57DA%2Fuploads%2FULBmX15cNRkZ8Z72C7wn%2Funitypro1.png?alt=media\&token=2a9b32e7-5442-479d-83b1-32c73116f856)

### **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

1. Select NativeiOSApp target from NativeiOSApp project.
2. In "General" tab / "Frameworks, Libraries, and Embedded Content" press **+**.
3. Add Unity-iPhone/UnityFramework.framework.

   <figure><img src="https://4128853559-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlDytDSBRx8P4ZZXD57DA%2Fuploads%2FiWqDqdS7ilNVhvxYtcMe%2Fframework.png?alt=media&#x26;token=2a8b0401-579e-440c-839d-54ed6f16a1b6" alt=""><figcaption></figcaption></figure>
4. In "Build Phases" tab, expand "Link Binary With Libraries".
5. Remove UnityFramework.framework from the list (select it and press **-** ).

   <figure><img src="https://4128853559-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlDytDSBRx8P4ZZXD57DA%2Fuploads%2FqMCRCbfLt5ELZJltc2Gz%2Fbuildphases.png?alt=media&#x26;token=8add6757-4a08-4104-ba1a-35e958c6befb" alt=""><figcaption></figcaption></figure>

### **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.

1. Change Target Membership for Data folder to UnityFramework.

   <figure><img src="https://4128853559-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlDytDSBRx8P4ZZXD57DA%2Fuploads%2FeULONY1hqTSEpFTFr7eC%2Fpath.png?alt=media&#x26;token=acba677d-7927-43a6-8486-a51d264cf789" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://4128853559-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlDytDSBRx8P4ZZXD57DA%2Fuploads%2FPz8eLeEE3WDLf5BuS7TN%2Finfop.png?alt=media&#x26;token=cbc2de25-d1f7-4d8b-a03e-43c9e118aafb" alt=""><figcaption></figcaption></figure>

### 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.

{% code title="ContentView\.swift" %}

```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Button(action: {
            Unity.shared.show()
        }) {
            Text("Launch ARway!")
        }
    }
}
```

{% endcode %}

Next, update the **ViewController.swift** file to match the following.

{% code title="ViewController.swift" %}

```swift
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)
    }
}

```

{% endcode %}

Next, implement the connection between the Unity SDK and the Swift app. A new singleton called **Unity.swift** is created with the following code.

{% code title="Unity.swift" %}

```swift
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()
    }
}
```

{% endcode %}

Next update the **AppDelegate.swift** file to pass the main window reference to Unity.

{% code title="AppDelegate.swift" %}

```swift
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
    }
}
```

{% endcode %}

You should now be able to build and run the project on an iOS device.

{% hint style="info" %}
To run the app, you will need to use a physical device and not a simulator.
{% endhint %}

{% hint style="info" %}
Additional information about integrating Unity as a library into a standard iOS app can be found in the following links:&#x20;

<https://github.com/Unity-Technologies/uaal-example/blob/uaal-example/19LTS-21LTS/docs/ios.md>

<https://docs.unity3d.com/2019.3/Documentation/Manual/UnityasaLibrary.html>
{% endhint %}
