A guide to integrating full-body scanning into your iOS app.
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:
CaptureSession drives the capture through a linear state machine. Your app
observes state changes via Combine @Published properties and the SDK handles transitions automatically:
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.
NSCameraUsageDescription in Info.plist)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.
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"
)
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)
Use PrismSessionView (SwiftUI) or PrismSessionViewController (UIKit) to present the full capture flow.
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
}
)
}
}
}
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)
}
}
CaptureSession.isSupported before presenting the capture view. Devices without a TrueDepth camera will fail with CaptureError.unsupportedDevice.
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
)
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)
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
)
PrismSessionView — SwiftUI capture flow viewPrismSessionViewController — UIKit capture flow controllerCaptureSession — Core capture orchestratorCaptureSessionState — State enum (idle through finished)CaptureSessionConfiguration — Recording mode and pose themePrismThemeConfiguration — UI color, font, icon, and styling customizationApiClient — HTTP client for backend communicationUserClient — User creation and managementScanClient — Scan CRUD, upload URLs, measurements, health reportsScan / NewScan — Scan data modelsMeasurements — 28+ body circumference measurementsHealthReport — Body fat, metabolism, percentile analysisSee the API Reference for full type documentation.