Skip to content
English
  • There are no suggestions because the search field is empty.

Integration Guide

Package name (shown in Xcode): FBxSDK

Swift Package Registry identity: product.ios-sdk

Version: 0.3.1

Platform: iOS 17+

Xcode: 26+

Orientation: Portrait only

Delivery: Swift Package via Swift Package Registry


1) Overview

FBxSDK provides a SwiftUI integration point and a small public API designed for straightforward embedding into an iOS application using:

  • A SwiftUI view (FBxView) that hosts the SDK’s rendering surface
  • A manager singleton (FBxManager.shared) that provides configuration + lifecycle control (configure, start, stop, setFrame) and emits events

High-level lifecycle:

  1. Configure (validates license online)
  2. Attach view (FBxView) → SDK prepares and becomes ready
  3. Explicitly start/stop the try-on session

2) Distribution & installation

FBxSDK is distributed via Swift Package Registry.

One-time registry setup and login

Configure the registry scope and login once on your machine :

swift package-registry set --global --scope product https://fittingbox.jfrog.io/artifactory/api/swift/product.swift
swift package-registry login \
--username client-swift-sdk \
--password '<PASSWORD>' \
--no-confirm \
https://fittingbox.jfrog.io/artifactory/api/swift/product.swift

Add package dependency

Add the package to your project using:

  • Xcode → File → Add Package Dependencies…
  • Package identity: product.ios-sdk
  • Version: exact 0.3.1

Notes / Troubleshooting

  • After setting the Swift Package Registry scope, it is recommended to restart Xcode, as it may not refresh registry sources until relaunch.
  • In the Add Package Dependencies search, even if the full package identity (product.ios-sdk ) is typed in, Xcode can incorrectly show no packages found. Pressing enter usually resolves this issue, as it forces the lookup and the package should appear.


3) App-level requirements & constraints

Camera permission handling

Camera permission is intentionally treated as an application concern, as UX, timing, copy, and fallback flows tend to be product-specific.

The standard iOS camera usage string is expected in the host app’s Info.plist:

  • NSCameraUsageDescription

If camera permission is not granted, start() fails with a cameraPermissionDenied error.

Portrait mode

FBxSDK is designed for portrait usage only.


4) Integration model

FBxSDK follows a three-phase model: configure/prepare first, then run.

Phase A - Configure (explicit)

Call configure(_:) with FBxConfiguration that contains an apiKey and optional startFrameId :

  • Validates the license via network call
  • Stores apiKey and optional startFrameId
  • Transitions to .configured (or .configurationFailed)

Phase B - Attach / prepare (automatic)

When FBxView is on-screen and has a non-trivial size:

  • The SDK transitions .configured → .preparing → .ready

Phase C - Run session (explicit)

  • start() starts the try-on session and renders the camera inside FBxView
  • stop() stops the session and returns to .ready

5) Public API surface

5.1 FBxView

FBxView is the SwiftUI entry point and rendering container.

  • Should be full-screen
  • When start() is called, the camera preview is rendered inside this view

5.2 FBxManager

Singleton access:

  • FBxManager.shared

Primary methods:

  • configure(_ configuration: FBxConfiguration) - validates the apiKey and stores it, also stores an optional startFrameId , which will be used as the initial frame when the try-on session starts (async, can throw)
  • start() - starts the try-on session (async, can throw)
  • stop() - stops the try-on session (async, can throw)
  • setFrame(_ id: String) - sets a selected frame by its ID (async, can throw)

Observability:

  • events - an AsyncStream<FBxEvent> (see below)
  • state - current FBxState

5.3 FBxConfiguration

FBxConfiguration is a lightweight configuration value passed into FBxManager.shared.configure(_:).

It contains:

  • apiKey: String - required
  • startFrameId: String? - optional (used as the initial frame when the session starts)


6) State model

FBxState reflects configuration, preparation, and session lifecycle:

  • unconfigured - no configuration provided yet
  • configuring - validating/applying configuration
  • configured - configured successfully, no view/session active
  • configurationFailed - configuration failed, must re-configure
  • preparing - preparing triggered by FBxView layout/attachment
  • ready - ready for start()
  • starting - start requested, session bootstrapping in progress
  • active - session is active (camera preview visible in FBxView)
  • stopping - stop requested, session shutting down

State transitions are emitted via the event stream.


7) Events

events emits FBxEvent updates and supports multiple concurrent subscribers, including an immediate .stateChanged(currentState) on subscription.

In the current skeleton version, it contains the following two events:

  • stateChanged(FBxState)
  • frameLoaded(String)

8) Errors

FBxError represents failures that can be thrown by the FBxSDK:

  • Configuration
    • configurationNotSet
    • configurationFailed
    • invalidAPIKey
    • noInternetConnection
  • Lifecycle / ordering
    • invalidState(String)
  • Camera
    • cameraPermissionDenied
    • cameraPermissionNotGiven
    • cameraError(String)
  • Generic
    • internalError(String)

9) Usage example

import SwiftUI
import FBxSDK

@main
struct FBxSDKTestApp: App {
var body: some Scene {
WindowGroup {
NavigationStack {
ContentView()
}
.task {
do {
try await FBxManager.shared.configure(
FBxConfiguration(apiKey: "123", startFrameId: nil)
)
} catch {
print("configuration failed: \\(error)")
}
}
}
}
}

struct ContentView: View {
@State private var state: FBxState?

var body: some View {
ZStack(alignment: .top) {
FBxView()
.ignoresSafeArea()

VStack(spacing: 16) {
Text("SDK State: \\(state?.description, default: "nil")")
.font(.footnote)

HStack(spacing: 12) {
Button("Start") {
Task {
do { try await FBxManager.shared.start() }
catch { print("start failed: \\(error)") }
}
}

Button("Stop") {
Task {
do { try await FBxManager.shared.stop() }
catch { print("stop failed: \\(error)") }
}
}
}

Button("Set Frame A") {
Task {
do { try await FBxManager.shared.setFrame("A") }
catch { print("setFrame failed: \\(error)") }
}
}
}
.padding()
}
.task {
for await event in FBxManager.shared.events {
switch event {
case .stateChanged(let newState):
state = newState
case .frameLoaded:
break
@unknown default:
break
}
}
}
}
}

10) Operational notes

  • configure(_:) must complete successfully before starting a session
  • start() requires state == .ready
  • stop() is to be called when leaving the screen or exiting the experience

start()/stop() can be called repeatedly (e.g. start → stop → start) as long as each start() happens when the SDK is back in .ready state.


11) Integration checklist

  • Xcode 26+
  • Swift Package Registry scope configured
  • Package added
  • NSCameraUsageDescription included in Info.plist
  • Internet access available
  • SDK configured via configure(_:)
  • Hosting screen locked to portrait
  • FBxView placed in the UI hierarchy
  • Application observes events for UI and troubleshooting
  • Session controlled via start() / stop()