# Swift Package The Swift package exposes Sipp to native macOS and iOS applications. It supports local GGUF model registration, named local endpoints, query, chat, embedding, streaming tokens, cancellation, typed errors, and sandbox-friendly file access. Swift support is still in development and is not published as a remote SwiftPM package yet. Today, build it from a source checkout on macOS. See the [Library API Overview](../api) for the shared `add`, `query`, `chat`, and `embed` contracts. ## Install From Source Swift builds require macOS, Xcode, CMake, Ninja, and the Apple Rust targets: ```bash cargo xtask toolchain install rust-apple cargo xtask doctor --target swift cargo xtask build swift ``` The build has no backend selector or runtime fallback. Each XCFramework slice has one backend chosen for its platform and architecture: | Platform | Architectures | Backend | | --- | --- | --- | | macOS | arm64 | Metal | | macOS | x86_64 | CPU | | iOS device | arm64 | Metal | | iOS Simulator | arm64, x86_64 | CPU | SwiftPM selects the matching slice when it links the application. Metal-capable Apple silicon devices therefore use Metal, while Intel macOS and simulator builds use CPU code. A Metal initialization failure is reported as an error; it does not silently rerun the request on CPU. The build writes a complete local Swift package to: ```text .build/artifacts/swift/package ``` Point your application package dependency at that directory while developing against an untagged checkout. A remote SwiftPM URL will be documented after the versioned `SippCore.xcframework` archive is published. ## Use It For - Native macOS and iOS applications that need local GGUF inference. - Sandboxed apps that receive model files from a system file picker. - Query, chat, embedding, token streaming, and cancellation. - Deterministic Metal or CPU execution selected by the linked platform slice. Gateway, direct provider, Objective-C, and other Apple-platform APIs are outside the initial Swift package scope. ## Local Chat ```swift import Sipp let client = try SippClient() let model = try await client.models.add([modelURL]) try await client.add("local", model: model) let run = client.chat( messages: [ ChatMessage(role: .system, content: "Answer concisely."), ChatMessage(role: .user, content: "Explain on-device inference."), ], endpoint: "local", options: TextOptions(maxTokens: 64) ) for await batch in run.tokens { print(batch.text, terminator: "") } let response = try await run.response print(response.text) ``` `TextRun.tokens` is a consumptive `AsyncSequence`. `TextRun.response` is cached, so multiple awaits observe the same terminal result. ## Query And Embedding Use `query` for raw prompts: ```swift let run = client.query( "Explain Sipp in one sentence.", endpoint: "local", options: TextOptions(maxTokens: 64) ) print(try await run.response.text) ``` Use `embed` with a model that supports embeddings: ```swift let run = client.embed( "Text to embed", endpoint: "local", local: LocalEmbedOptions(normalize: true) ) let embedding = try await run.response print(embedding.values.prefix(8)) ``` Call `cancel()` on any active run to request native cancellation: ```swift run.cancel() ``` Cancelling a Swift task that is awaiting tokens or a response also requests cancellation. ## Models And Endpoints Create one client per application storage root: ```swift let client = try SippClient() ``` When `storageRoot` is omitted, Sipp uses the user's Application Support directory. To use a custom location, pass a file URL: ```swift let client = try SippClient(storageRoot: appStorageURL) ``` Register local file URLs or HTTP(S) model sources: ```swift let model = try await client.models.add([modelURL]) let models = try await client.models.list() try await client.models.remove(model) ``` Endpoints are caller-owned strings: ```swift try await client.add("local", model: model) try await client.remove("local") ``` Removing a model fails while an endpoint still uses it. Remove the endpoint first, then remove the model. ## App Sandbox For sandboxed macOS apps, pass the `URL` returned by a system file picker directly to `client.models.add`. Do not convert it to a path before Sipp receives it. Files already inside the application container remain zero-copy and are stored relative to that container, so their registration survives container relocation. Files outside the container use security-scoped bookmarks. Sipp resolves those bookmarks when an endpoint first activates the registered model, not while the client is being initialized. The sandboxed app needs these entitlements for local model files: ```xml com.apple.security.app-sandbox com.apple.security.files.bookmarks.app-scope com.apple.security.files.user-selected.read-only ``` Add `com.apple.security.network.client` only when registering HTTP(S) model sources. ## Examples `cargo xtask build swift` builds a command-line example and a sandboxed SwiftUI example for macOS, plus a SwiftUI iOS example: ```bash .build/artifacts/swift/examples/SippCLI chat /path/to/model.gguf \ "Explain on-device inference" open .build/artifacts/swift/examples/SippSandbox.app cargo xtask run examples ios --simulator SIMULATOR-UDID \ --model /path/to/model.gguf ``` The CLI supports `query`, `chat`, `embed`, and `cancel`. The SwiftUI example uses a system importer, streams chat tokens, runs embeddings, shows typed errors, and supports cancellation. See [`examples/swift`](../../../examples/swift/README.md). ## Troubleshooting - Run `cargo xtask doctor --target swift` before building. - If an Apple Rust target is missing, run `cargo xtask toolchain install rust-apple`. - If `SippCore.xcframework` is missing, depend on the staged package under `.build/artifacts/swift/package`, not `lib/swift`. - If an external sandboxed model file is unavailable when its endpoint is activated, keep the same signed app identity and inspect the typed bookmark error. App-container model files do not depend on bookmarks. - If embedding fails, use a GGUF/runtime with embedding support. - If Metal is unavailable, the package uses the core CPU behavior. ## Related Docs - [Examples And Demos](../examples-demos.md) - [Runtime Options](../reference/runtime-options.md) - [Source Builds](../maintainers/source-builds.md)