SmartSpectraSDK
Entry point for the SmartSpectra SDK.
Most apps use the shared instance:
let sdk = SmartSpectraSDK.shared
sdk.config.apiKey = "your-key"
try await sdk.start()
Tests and advanced integrations can create an isolated instance via init(config:). The underlying authentication handler and C++ preprocessing runtime are process-global, so only one SDK instance can drive an active measurement at a time.
Initializers
-
public init (config: SmartSpectraConfig)Create an isolated SDK instance backed by the given configuration.
The authentication handler and preprocessing runtime are process-global, so only one instance can drive an active measurement at a time. Use this initializer for tests or advanced integrations where you intentionally need a separate observable state from
shared. Most apps should just useSmartSpectraSDK/shared.
Methods
-
public func start () async throwsBegin processing the selected input (device camera by default). In custom mode, await this call before submitting frames.
-
public func stop () async throwsStop processing. Call
start()again to resume. -
public func useCustomInput (frameTransform: FrameTransform = .none) throws -> CustomInputSelect caller-owned video input while stopped. No SDK camera discovery, capture, or camera permission is required. Selecting a source invalidates older custom-input handles. Throws
.invalidStateduring startup or processing. -
public func useCamera (_ selection: CameraSelection) throwsSelect camera capture while stopped. Default prefers front, then the first discovered camera. Explicit selections never fall back. Selection is resolved at capture startup; an unavailable camera fails start with
.inputUnavailable. Throws.configurationFailedfor an empty ID and.invalidStatewhile busy. Rejected requests preserve the previous source. Stop/start/reset retain the selection until another source is selected. This call does not open a camera. -
@available(*, deprecated, message: "Pass an explicit CameraSelection, such as .default or .byId(id).") public func useCamera () throwsSelect camera capture using the legacy config.cameraPosition behavior.
-
public nonisolated static func availableCameras () throws -> [CameraInfo]Discover cameras without constructing or authenticating an SDK instance, requesting permission, or starting capture. Visibility depends on platform permissions; a snapshot does not guarantee capture will succeed later. Throws
.inputUnavailableif discovery fails. -
public func reset () async throwsStop processing and clear measurement output, retaining configuration, the selected source, transform, and custom-input handle. Safe while idle; await before restarting.
-
@discardableResult public func requestInsight (_ text: String) throws -> Int32Dispatch an on-demand insight request alongside the vitals samples buffered since the last send.
The provided
textis sent as the current turn’s prompt; prior calls’ text is not retained or re-sent by the SDK. The deliveredInsightalways hastype == .vitalstoday (.speechand.combinedare reserved and not emitted). Vitals snapshots auto-fire — one as each of pulse rate, breathing rate, and HRV first stabilises, then one every 60 seconds — carrying a fixed SDK-supplied prompt rather than caller text, and are published throughSmartSpectraSDK/insightalongside on-demand replies, so match a reply to its prompt withrequestID, nottype. -
@_spi(Testing) public func setVideoInput (path: String)Configures a video file as input source instead of the live camera. Supported formats: .mov, .mp4, .qt
-
@_spi(Testing) public func setVideoTimestampInput (path: String)Configures optional timestamp file (one ms value per line) for frame timing.
-
@_spi(Testing) public func setVideoInterframeDelay (milliseconds: Int)Configures optional video-file playback throttling in milliseconds.
-
@_spi(Testing) public func setVideoInputEnabled (_ enabled: Bool)Selects testing file input or camera input while stopped. An active-session selection is rejected and reported through
error.
Properties
-
public static let shared = SmartSpectraSDK()The shared SDK instance.
-
public internal(set) var metrics : Metrics?Real-time metrics emitted while processing is active.
-
public internal(set) var imageOutput : UIImage?Live camera preview image.
-
public internal(set) var processingStatus : ProcessingStatus = .idleCurrent processing pipeline status.
-
public internal(set) var error : SmartSpectraError?Latest error from the SDK.
-
public internal(set) var validationStatus : ValidationStatus?Measurement readiness: face position, lighting, etc. Only meaningful while
processingStatusis.running. -
public internal(set) var insight : Insight?Latest insight from the AI insights service.
-
public nonisolated static var version : StringSDK version string.
-
public let config : SmartSpectraConfigConfiguration for this SDK instance.
Mutate properties on this object rather than replacing it.
SmartSpectraConfig
Configuration for SmartSpectraSDK.
Access configuration through SmartSpectraSDK/config rather than constructing one directly:
let sdk = SmartSpectraSDK.shared
sdk.config.apiKey = "your-key"
Standalone construction is available for tests and advanced integrations that pass a custom config into SmartSpectraSDK/init(config:).
Initializers
-
public init ()Creates a configuration with default values. Prefer
SmartSpectraSDK/configover constructing a standalone config unless you are driving an isolatedSmartSpectraSDKinstance.
Properties
-
@available(*, deprecated, message: "Use sdk.useCamera(.front), .back, or .byId instead.") public var cameraPosition : AVCaptureDevice.Position = .frontLegacy camera position, used until an explicit camera selector is chosen.
-
public var logLevel : SmartSpectraLogLevel = .defaultVerbosity of SDK logging — both the SDK’s Swift-side logging and the native engine. Takes effect immediately when set (like
imageOutputEnabled). Defaults toSmartSpectraLogLevel/warning(warnings and errors only). -
public var imageOutputEnabled : Bool = trueControls whether the SDK publishes preview frames to
SmartSpectraSDK/imageOutput.When disabled, camera frames are still processed for vitals analysis, but the SDK skips
CVPixelBuffertoUIImageconversion and preview updates. This is useful for custom integrations that do not display a live camera feed.Example:
let sdk = SmartSpectraSDK.shared sdk.config.imageOutputEnabled = false- Note: Changes take effect immediately and do not require restarting processing.
-
public var enableTelemetry : Bool = trueControls whether the SDK reports anonymous, aggregate usage telemetry.
Telemetry is on by default; set this to
falseto opt out. When enabled, the SDK sends a per-session summary. It does not include raw frames, metric values, file paths, user identifiers, or device identifiers. Reporting is best-effort and never blocks or affects a measurement session.Example:
let sdk = SmartSpectraSDK.shared sdk.config.enableTelemetry = false- Note: Read when a measurement session starts.
-
public var apiKey : String?API key from the Presage developer portal. Setting this automatically configures authentication.
-
public var requestedMetrics : [MetricType]?Which metrics to compute during processing.
This property provides granular control over which metric families the SDK requests. Derived feature flags such as cardio and face processing are inferred from the selected metric types.
Duplicate metrics are removed automatically while preserving the original order.
If you do not set this property, the SDK defaults to breathing-only metrics: chest breathing, abdomen breathing, breathing rate, breathing amplitude, apnea, respiratory line length, baseline, and inhale/exhale ratio.
Example:
let sdk = SmartSpectraSDK.shared sdk.config.requestedMetrics = [ .breathingRate, .pulseRate, .faceLandmarks ]Example using the predefined bundles:
config.requestedMetrics = SmartSpectraConfig.breathingMetrics + SmartSpectraConfig.cardioMetrics -
public nonisolated static let breathingMetrics : [MetricType]Breathing metric bundle. Equivalent to leaving
SmartSpectraConfig/requestedMetricsunset. -
public nonisolated static let cardioMetrics : [MetricType]Cardio metric bundle (pulse rate, arterial pressure trace, HRV). Combine with
breathingMetricsfor the typical “vitals” bundle. -
public nonisolated static let faceMetrics : [MetricType]Face metric bundle (landmarks, blinking, talking, expressions).
-
public nonisolated static let edaMetrics : [MetricType]EDA Proxy (electrodermal activity) trace metric bundle.
CustomInput
Caller-owned video input obtained from SmartSpectraSDK/useCustomInput(frameTransform:).
The handle survives stop/start and reset. Selecting another source invalidates it. Await sdk.start() before submitting frames from a serial worker queue. Keep each buffer alive and unchanged until submission returns; the SDK retains no borrowed pixels. Calls are serialized with native teardown. This type is safe to share across threads; callers remain responsible for ordering timestamps and synchronizing buffer mutations.
Methods
-
public func sendFrame (_ pixelBuffer: CVPixelBuffer, timestampUs: Int64) -> FrameSubmissionResultSubmits BGRA or 8-bit bi-planar NV12 (video or full range) pixels.
Timestamps are nonnegative, strictly increasing microseconds on one monotonic timeline per run, below
Int64.max - 2. Gaps greater than two seconds are rejected; stop and start again after an interruption. Row padding and separate NV12 planes are supported. NV12 is converted to BGRA before submission. Unsupported formats return.rejectedwith.frameConversionFailed.Pixels must already have the desired orientation, or select a session transform. Camera position and preview mirroring do not transform caller-owned frames.
-
public func sendFrame (_ sampleBuffer: CMSampleBuffer) -> FrameSubmissionResultSubmits the image and presentation timestamp of an uncompressed video sample. The timestamp is converted to microseconds; invalid, indefinite, infinite, negative, or out-of-range timestamps are rejected. Orientation is not inferred from metadata.
FrameTransform
Spatial transform applied to every frame in a custom-input session.
case none = 0case rotate90CW = 1case rotate90CCW = 2case rotate180 = 3case mirrorHorizontal = 4case mirrorVertical = 5
ProcessingStatus
Indicates the current state of the preprocessing pipeline.
case idlecase startingcase runningcase stoppingcase error
ValidationStatus
Measurement readiness: a stable code plus a human-readable hint. Orthogonal to ProcessingStatus (engine lifecycle).
Properties
-
public let code : ValidationCodeThe stable, machine-readable readiness code.
-
public let hint : StringA human-readable hint describing what needs to change for a valid measurement.
ValidationCode
Measurement-readiness codes.
case ok = 0case noFaceFound = 1case multipleFacesFound = 2case faceNotCentered = 3case faceSizeOutOfRange = 4case tooDark = 5case tooBright = 6case chestNotVisible = 7case cameraTuning = 10case frameRateTooLow = 11case excessiveMotion = 12case faceTooClose = 13case faceTooFar = 14case faceTooHigh = 15case faceTooLow = 16case faceNotForward = 17
SmartSpectraError
A typed error from the SmartSpectra SDK.
Thrown by SmartSpectraSDK/start() and SmartSpectraSDK/stop(), and published on SmartSpectraSDK/error for async pipeline failures.
Properties
-
public let code : CodeThe error category.
-
public let message : StringA human-readable description of what went wrong.
-
public let retryable : BoolWhether the operation that produced this error can be retried.
-
public var errorDescription : String?A human-readable description of the error; returns
message.
SmartSpectraError.Code
SDK error codes. No .ok case — in Swift, success means no error thrown.
Raw values are stable across SDK versions and match the C++/Android wire values.
case invalidState = 1case authenticationFailed = 2case configurationFailed = 3case creditExhausted = 4case networkError = 5case serverError = 6case inputUnavailable = 7case processingFailed = 8case frameConversionFailed = 9case nonMonotonicTimestamp = 10case timestampGap = 11
CameraSelection
A camera request resolved when capture starts. Explicit selections never fall back.
case `default`case frontcase backcase byId(String)
CameraFacing
Direction reported by the camera. External cameras may report .unknown.
case frontcase backcase unknown
CameraLensType
Best-effort lens classification, independent of digital zoom. Missing metadata and cameras combining multiple lenses report .unknown.
case unknowncase wideAnglecase ultraWidecase telephoto
CameraInfo
A discoverable camera. IDs are opaque and device-local; availability can change.
Initializers
-
public init (id: String, name: String? = nil, facing: CameraFacing = .unknown, lensType: CameraLensType = .unknown)
Properties
-
public let id : String -
public let name : String? -
public let facing : CameraFacing -
public let lensType : CameraLensType
FrameSubmissionResult
Acceptance means the pixels were consumed, not that measurement processing has finished.
case acceptedcase rejected(SmartSpectraError)
SmartSpectraLogLevel
Verbosity of SDK logging, set via SmartSpectraConfig/logLevel.
Levels are cumulative: a level shows its own messages plus everything more severe. The setting covers both the SDK’s Swift-side logging and the native engine. debug cannot restore debug-only statements that were compiled out of the release engine binary.
Raw values are stable across SDK versions and match the C++/Android wire values.
case debug = 0case info = 1case warning = 2case error = 3case none = 4