Xybrid
SDKs

iOS / macOS

Native Swift SDK for on-device ML inference

The Swift SDK provides native bindings to the Xybrid runtime via UniFFI for iOS and macOS applications.

The Swift SDK is in early access. Releases ship a prebuilt XybridFFI xcframework via Swift Package Manager. Known issue: building for the iOS Simulator on Apple Silicon requires the useLocalNatives = true workaround — see #179. For cross-platform development, see the Flutter SDK.

Installation

Add the Xybrid package via Swift Package Manager:

Package.swift
dependencies: [
    .package(url: "https://github.com/xybrid-ai/xybrid", from: "0.2.2")
]

Or in Xcode: File > Add Package Dependencies and enter the repository URL.

Supported platforms: iOS 13.0+, macOS 10.15+

Quick Start

import Xybrid

@main
struct MyApp: App {
    init() { Xybrid.initialize() }
    var body: some Scene { /* ... */ }
}

// Load a model from the registry
let loader = ModelLoader.fromRegistry(modelId: "kokoro-82m")
let model = try loader.load()

// Run inference
let envelope = Envelope.text("Hello, world!")
let result = try model.run(envelope: envelope)

if result.success {
    print("Output: \(result.text ?? "")")
    print("Latency: \(result.latency)s")
}

On iOS, Xybrid.initialize() enables UIDevice battery monitoring and subscribes to UIDevice.batteryLevelDidChangeNotification, forwarding readings to the routing engine. Thermal state on Apple platforms is sourced from NSProcessInfo.thermalState directly in xybrid-core.

Initialization

Inference runs entirely on-device whether or not you authenticate. Pass an apiKey to light up the dashboard — that single call starts the telemetry exporter, and your model.run(...) calls automatically emit execution traces:

Xybrid.initialize(
    apiKey: ProcessInfo.processInfo.environment["XYBRID_API_KEY"]
)

Without a key, telemetry is disabled and the first inference logs a one-shot hint pointing at the dashboard (suppress with the XYBRID_QUIET=1 environment variable). Get a free key at dashboard.xybrid.dev. For a self-hosted dashboard, also pass ingestUrl.


Model Loading

From Registry

let loader = ModelLoader.fromRegistry(modelId: "whisper-tiny")
let model = try loader.load()

From Local Bundle

let loader = ModelLoader.fromBundle(path: bundlePath)
let model = try loader.load()

Input Envelopes

Audio (Speech Recognition)

let envelope = Envelope.audio(pcmData: audioData, sampleRate: 16000, channels: 1)
let result = try model.run(envelope: envelope)
print("Transcription: \(result.text ?? "")")

Text (Text-to-Speech)

// Simple text
let envelope = Envelope.text("Hello, how are you?")

// With voice and speed
let envelope = Envelope.text("Hello", voice: "af_heart", speed: 1.0)

let result = try model.run(envelope: envelope)
if let audioBytes = result.audioBytes {
    // Play or save audio
}

Embedding

let envelope = Envelope.embedding(data: [0.1, 0.2, 0.3])
let result = try model.run(envelope: envelope)
if let vector = result.embedding {
    // Process embedding vector
}

Result Handling

let result = try model.run(envelope: envelope)

if result.success {
    switch result.outputType {
    case "text":
        print("Text: \(result.text!)")
    case "audio":
        playAudio(result.audioBytes!)
    case "embedding":
        process(result.embedding!)
    default:
        break
    }
    print("Latency: \(result.latency)s")  // TimeInterval in seconds
} else {
    print("Error: \(result.error ?? "Unknown")")
}

XybridResult Properties

PropertyTypeDescription
successBoolWhether inference succeeded
errorString?Error message if failed
outputTypeString"text", "audio", or "embedding"
textString?Text output (ASR, LLM)
audioBytesData?Audio output (TTS)
embedding[Float]?Embedding vector
latencyMsUInt32Inference latency in ms
isFailureBoolConvenience: !success
latencyTimeIntervalLatency in seconds

Error Handling

The SDK uses a Swift error enum for type-safe error handling:

do {
    let model = try ModelLoader.fromRegistry(modelId: "kokoro-82m").load()
    let result = try model.run(envelope: envelope)
} catch XybridError.ModelNotFound(let modelId) {
    print("Model not found: \(modelId)")
} catch XybridError.InferenceFailed(let message) {
    print("Inference failed: \(message)")
} catch XybridError.InvalidInput(let message) {
    print("Invalid input: \(message)")
} catch XybridError.IoError(let message) {
    print("I/O error: \(message)")
} catch {
    print("Unexpected error: \(error.localizedDescription)")
}

Type Aliases

The SDK provides short aliases for convenience:

AliasFull Type
ModelLoaderXybridModelLoader
ModelXybridModel
EnvelopeXybridEnvelope
ResultXybridResult

Platform Support

PlatformStatusAccelerators
iOSSupportedMetal, CoreML, ANE
macOS (Apple Silicon)SupportedMetal, CoreML, ANE
macOS (Intel)SupportedCPU

On this page