Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Install the Swift SDK

Prerequisites

Swift 6.1 or later. The package manifest uses Swift tools 6.1 and Swift 6 language mode.

Building libpanproto_c from source additionally needs a Rust toolchain; rustup is recommended. The prebuilt path below needs neither Rust nor a workspace checkout.

Install

The package is not yet on a registry; it lives at bindings/swift/ in the repository. Engine-backed products link libpanproto_c, the C application binary interface exposed by the panproto-c crate. Stage that library before building an engine-backed target. PanprotoStructural is a pure Swift product and does not call the engine.

Build from source

bootstrap/dev-link.sh runs cargo build -p panproto-c --release, stages the resulting library and header under bindings/swift/.panproto-c/, and syncs the vendored copy of panproto.h that the package compiles against. Package.swift looks in .panproto-c/lib by default, so nothing else needs configuring.

git clone https://github.com/panproto/panproto.git
cd panproto/bindings/swift
./bootstrap/dev-link.sh
swift build
swift test

Run dev-link.sh again after every change to panproto-c or the workspace Cargo.toml. Set PANPROTO_C_LIB_DIR to stage somewhere else.

Prebuilt binaries

bootstrap/fetch-bindist.sh [version] [variant] downloads the prebuilt library for the host platform from the corresponding GitHub Release. It detects aarch64-apple-darwin, x86_64-apple-darwin, x86_64-unknown-linux-gnu, and aarch64-unknown-linux-gnu. Both arguments are optional and are read by shape rather than by position, so either can be given alone: the version defaults to whatever the checkout declares, and the variant (default or full, also spelled --default and --full) defaults to default.

cd panproto/bindings/swift
./bootstrap/fetch-bindist.sh
swift build

XCFramework

iOS builds go through the XCFramework, which carries a macOS-universal slice, an iOS device slice, and a universal simulator slice, together with the headers and a module map.

cd panproto/bindings/swift
./bootstrap/fetch-bindist.sh --xcframework
PANPROTO_SWIFT_XCFRAMEWORK=.panproto-c/panproto_c.xcframework swift build

To depend on the package from another project, point PANPROTO_SWIFT_XCFRAMEWORK_URL and PANPROTO_SWIFT_XCFRAMEWORK_CHECKSUM at the published artifact and its checksum, both of which the release attaches. That mode adds no linker flags of its own, which is what makes the package usable as a dependency; the dev-link.sh mode passes an unsafe -L flag and is for building the package directly.

Products

ProductContents
PanprotoStructuralThe pure value layer: schemas, chains, migrations, and instances as Swift values, plus the CBOR codec. No engine, no FFI.
PanprotoThe engine-backed core: protocols, schemas, instances, I/O codecs, compatibility checking, migrations, lenses, expressions, theories, enrichment, homomorphism search, graph fibers, and datasets.
PanprotoVcsSchematic version control.
PanprotoParseFull-AST source parsing. Feature-gated.
PanprotoProjectMulti-file project assembly. Feature-gated.
PanprotoGitThe git bridge. Feature-gated.

Feature-gated tiers

The default libpanproto_c omits the parse, project, and git tiers. Using one of those tiers requires a library built with the matching Cargo features and a Swift build that compiles the gated shims:

PANPROTO_C_FEATURES=full ./bootstrap/dev-link.sh
swift build --traits PANPROTO_PARSE,PANPROTO_PROJECT,PANPROTO_GIT

Each tier is a package trait, and a trait defines a compilation condition of its own name, which is what the #if PANPROTO_PARSE blocks in the gated sources read.

The three gated products exist in the package graph either way, so a build that omits the features still resolves; their modules are simply empty. On the prebuilt path, fetch the full variant:

./bootstrap/fetch-bindist.sh full
swift build --traits PANPROTO_PARSE,PANPROTO_PROJECT,PANPROTO_GIT

Verification

import Foundation
import Panproto
import PanprotoStructural

let names = try await ProtocolHandle.builtinNames()
print(names.count, "builtin protocols")

let atproto = try await ProtocolHandle.builtin("atproto")
let lexicon = try Data(contentsOf: URL(fileURLWithPath: "app.bsky.feed.post.json"))
let schema = try await SchemaHandle.parseAtprotoLexicon(lexicon)
let value = try await schema.schema()
print(value.protocolName, value.vertexCount, "vertices")

let messages = try await schema.violations(against: atproto)
print(messages.isEmpty ? "valid" : messages.joined(separator: "\n"))

Engine calls run on the @PanprotoEngine global actor, which is pinned to one thread. Release long-lived handles explicitly when their work is complete.