iOS SDK
Integrate Graffity AR Cloud using GraffityARCloudConfiguration and the public GraffityARCloud session class. These docs describe the 5.1.1 API.
Requirements
- An AR Cloud project and access token from Graffity Console.
- iOS 18.0 or later on an ARKit world-tracking capable physical device. Test camera tracking and VPS on a device.
- Xcode with the iOS 18 SDK or later and Swift 6 package tools support.
- Network access for venue lookup, localization, assets, and maps.
Install the SDK
In Xcode, choose File → Add Package Dependencies, then enter:
https://github.com/Graffity-Technologies/graffity-arcloud-ios.gitSelect 5.1.1 or a newer compatible 5.x release and add the GraffityARCloud library product to your app target. The package carries the binary framework and its dependencies. See Apple’s package installation guide .
Use import GraffityARCloud in your app’s Swift files.
Add permissions
Add both descriptions to your app target’s Info.plist, with wording appropriate for your app:
<key>NSCameraUsageDescription</key>
<string>Use the camera to locate you and display AR content in the venue.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Use your location to find nearby venues and start AR navigation.</string>The SDK requests when-in-use location authorization and camera access as needed when its view starts. Handle denied permissions through SDK errors. A seed location does not replace authorization.
Configure and initialize
Construct an immutable configuration, then initialize on the main actor with try:
import GraffityARCloud
@MainActor
func makeARSession(accessToken: String) throws -> GraffityARCloud {
let configuration = GraffityARCloudConfiguration(
accessToken: accessToken,
mode: .arContent
)
return try GraffityARCloud(configuration: configuration)
}Use .arContent to localize immediately and show AR content. The default, .navigation, opens a destination map first; selecting a destination starts localization and route guidance. The docked minimap is a separate opt-in with minimap: .enabled.
The configuration initializer does not throw. The SDK initializer checks the token’s basic format and throws GraffityARCloudError.invalidAccessToken for malformed input. Server authorization happens later and failures arrive through the delegate and state. See all configuration options.
Present the AR experience
Retain one SDK instance per logical session. AR starts when its hosted view appears; there is no public start() call.
UIKit
import UIKit
import GraffityARCloud
@MainActor
final class ARExperienceViewController: UIViewController,
@preconcurrency GraffityARCloudDelegate {
private let sdk: GraffityARCloud
private var arController: UIViewController?
init(accessToken: String) throws {
sdk = try GraffityARCloud(configuration: GraffityARCloudConfiguration(
accessToken: accessToken,
mode: .arContent
))
super.init(nibName: nil, bundle: nil)
sdk.delegate = self
}
required init?(coder: NSCoder) {
fatalError("Use init(accessToken:)")
}
override func viewDidLoad() {
super.viewDidLoad()
let controller = sdk.makeViewController()
arController = controller
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controller.view)
NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
controller.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
controller.view.topAnchor.constraint(equalTo: view.topAnchor),
controller.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
controller.didMove(toParent: self)
let closeButton = UIButton(type: .system)
closeButton.setTitle("Close", for: .normal)
closeButton.addTarget(self, action: #selector(closeExperience), for: .touchUpInside)
closeButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(closeButton)
NSLayoutConstraint.activate([
closeButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 12),
closeButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16)
])
}
@objc private func closeExperience() {
Task {
await endSession()
if let navigationController {
navigationController.popViewController(animated: true)
} else {
dismiss(animated: true)
}
}
}
func graffityARCloud(
_ sdk: GraffityARCloud,
didFailWith error: GraffityARCloudError
) {
// Route the message to your app's error UI.
print(error.localizedDescription)
}
// Call before dismissing or popping this host at the end of the session.
func endSession() async {
await sdk.shutdown()
arController?.willMove(toParent: nil)
arController?.view.removeFromSuperview()
arController?.removeFromParent()
arController = nil
}
}Create the host from your presenting controller and catch initialization failures:
@MainActor
func presentAR(from presenter: UIViewController, accessToken: String) {
do {
let controller = try ARExperienceViewController(accessToken: accessToken)
controller.modalPresentationStyle = .fullScreen
presenter.present(controller, animated: true)
} catch {
print(error.localizedDescription)
}
}Run on a device
Connect a supported device, choose it as the Xcode run destination, and run. Grant camera and location access. Scan the mapped venue and follow the camera guidance. In navigation mode, select a destination before scanning.
Use state.vpsState or didLocalizeIn to recognize localization. isSceneReady means the AR scene is running, not that VPS has found a section.
Continue with iOS options and the API reference. Report issues through the issue center.