← Back to versions

Getting Started with PrismSDK iOS

A guide to integrating full-body scanning into your iOS app.

Overview

PrismSDK captures full-body scans using the device camera and the Vision framework for pose detection. The SDK handles the entire capture workflow — camera setup, device leveling, user positioning guidance, pose validation, recording, and packaging — through a state machine that your app observes via Combine.

The end-to-end flow involves four stages:

  1. Setup — Initialize the API client and create a user
  2. Capture — Present the capture session view
  3. Upload — Create a scan record and upload the archive
  4. Results — Retrieve measurements and health reports

Session State Machine

CaptureSession drives the capture through a linear state machine. Your app observes state changes via Combine @Published properties and the SDK handles transitions automatically:

IDLE → VOLUME → FACE GUIDANCE → LEVELING → POSITIONING → POSING → RECORDING → PROCESSING → FINISHED

Each state corresponds to a step the user completes — adjusting volume, leveling the device, positioning their body, holding the correct A-pose, and then the actual recording. The SDK provides built-in UI for each step via PrismSessionView.

Requirements

Integration Steps

1 Add the Framework

Add PrismSDK.xcframework to your Xcode project. In your target's General tab, ensure it appears under Frameworks, Libraries, and Embedded Content with Embed & Sign selected.

Add the camera usage description to your Info.plist:

<key>NSCameraUsageDescription</key>
<string>Camera access is required to perform body scans.</string>

Place the PrismSDK-Info.plist file (provided by Prismlabs) in your app bundle. This contains the API base URL and client credentials.

2 Initialize the API Client

Create an ApiClient. It loads configuration from PrismSDK-Info.plist by default, or accepts explicit values.

import PrismSDK

// Uses PrismSDK-Info.plist configuration
let apiClient = ApiClient()

// Or provide explicit credentials
let apiClient = ApiClient(
    baseURL: URL(string: "https://api.example.com"),
    clientCredentials: "your-credentials"
)

3 Create a User

A user must exist before scans can be created. Use UserClient to create or fetch users. Terms of Service must be accepted.

let userClient = UserClient(client: apiClient)

let newUser = NewUser(
    token: "your-user-token",
    email: "user@example.com",
    sex: .male,
    region: "north_america",
    usaResidence: nil,
    birthDate: DateComponents(
        calendar: .current, year: 1990, month: 1, day: 1
    ).date!,
    weight: Weight(value: 180, unit: .pounds),
    height: Height(value: 72, unit: .inches),
    researchConsent: false,
    termsOfService: TermsOfService(
        accepted: true, version: "1.0"
    )
)

let user = try await userClient.create(user: newUser)

4 Present the Capture Session

Use PrismSessionView (SwiftUI) or PrismSessionViewController (UIKit) to present the full capture flow.

SwiftUI

import PrismSDK

struct ScanView: View {
    @State private var showScanner = false
    @State private var archiveURL: URL?

    var body: some View {
        Button("Start Scan") {
            showScanner = true
        }
        .fullScreenCover(isPresented: $showScanner) {
            PrismSessionView(
                receivedArchive: { url in
                    archiveURL = url
                },
                onStatus: { state in
                    // Track analytics
                },
                onDismiss: {
                    showScanner = false
                }
            )
        }
    }
}

UIKit

import PrismSDK

class ScanViewController: UIViewController,
    PrismSessionViewControllerDelegate {

    func startScan() {
        let vc = PrismSessionViewController(
            theme: .default,
            delegate: self
        )
        vc.modalPresentationStyle = .fullScreen
        present(vc, animated: true)
    }

    func prismSession(
        _ controller: PrismSessionViewController,
        didRecieveArchive archive: URL
    ) {
        // Handle the recording archive
    }

    func prismSession(
        _ controller: PrismSessionViewController,
        didChangeStatus status: CaptureSessionState
    ) {
        // Track state changes for analytics
    }

    func prismSession(
        willDismiss controller: PrismSessionViewController
    ) {
        controller.dismiss(animated: true)
    }
}
Check CaptureSession.isSupported before presenting the capture view. Devices without a TrueDepth camera will fail with CaptureError.unsupportedDevice.

5 Configure the Session (Optional)

Customize recording mode, face guidance, scan review, and theming.

// Recording mode
let config = CaptureSessionConfiguration(
    recordingMode: .frames  // or .video
)

// Enable face guidance
PrismSessionView(...)
    .environment(\.enableFaceGuidance, true)

// Enable scan review screen
PrismSessionView(...)
    .environment(\.useScanReview, true)

// Custom theme
let theme = PrismThemeConfiguration(
    primaryColor: .blue,
    secondaryColor: .cyan,
    titleFont: .custom("Avenir", size: 28),
    bodyFont: .custom("Avenir", size: 16),
    primaryButtonCornerRadius: 20
)

// SwiftUI
PrismSessionView(...)
    .applyTheme(theme)

// UIKit
let vc = PrismSessionViewController(
    theme: theme,
    delegate: self
)

6 Create a Scan and Upload

After capture, create a scan record in the backend, get a presigned upload URL, and upload the archive.

let scanClient = ScanClient(client: apiClient)

// Create the scan record
let newScan = NewScan(
    deviceConfigName: "iphone",
    userToken: user.token
)
let scan = try await scanClient.createScan(newScan)

// Get presigned upload URL
let uploadUrl = try await scanClient.uploadUrl(
    forScan: scan.id
)

// Upload the archive .zip to uploadUrl.url via HTTP PUT
// (use URLSession or your preferred HTTP client)

7 Retrieve Results

Once the backend processes the scan, retrieve measurements, body fat, and health reports.

// Poll or check scan status
let scan = try await scanClient.getScan(forScan: scanId)
// scan.status: .created -> .processing -> .ready

// Get body measurements (28 circumference values)
let measurements = try await scanClient.measurements(
    forScan: scanId
)
// measurements.waistFit, measurements.chestFit, etc.

// Get body fat data
let bodyfat = try await scanClient.getBodyFat(
    forScan: scanId
)

// Get comprehensive health report
let report = try await scanClient.getHealthReport(
    forScan: scanId
)
// report.bodyFatPercentageReport
// report.metabolismReport
// report.waistToHipRatioReport

// Get 3D asset URLs
let assets = try await scanClient.assetUrls(
    forScan: scanId
)

Key Types Reference

See the API Reference for full type documentation.