Swift SDK for the Arcane API, designed for iOS and macOS apps that need to talk to an Arcane manager or agent.
This package has two layers:
ArcaneAPI: generated fromSpec/openapi.jsonwith Apple'sswift-openapi-generatorand checked in as static Swift source.Arcane: a hand-written SDK facade with auth, token storage, environment scoping, generic REST helpers, and WebSocket streams.ArcaneGRPC: a gRPC client for the mobile-pairing surface (mobile.v1proto). Used by paired devices that authenticate with a long-lived device token.
ArcaneOIDC is a separate product for browser-based OIDC sign-in so apps that only use API keys or username/password auth do not link AuthenticationServices.
The generated OpenAPI Swift files are checked in under Sources/ArcaneAPI. App consumers do not need the OpenAPI generator installed and do not run code generation during their builds.
import Arcane
let client = ArcaneClient(
configuration: .init(
baseURL: URL(string: "https://arcane.example.com")!,
tokenStore: KeychainTokenStore(service: "com.example.app.arcane"),
defaultEnvironmentID: "0"
)
)
try await client.auth.login(username: "admin", password: "password")
let containers: [ContainerSummary] = try await client.containers.list(envID: "0")
try await client.containers.start(envID: "0", id: containers[0].id)
for try await line in client.containers.logs(envID: "0", id: containers[0].id, follow: true) {
print(line.text)
}The complete OpenAPI client is generated from Spec/openapi.json and checked in under Sources/ArcaneAPI. Consumers do not need swift-openapi-generator; only maintainers need it when refreshing the spec.
The Arcane product exports top-level Swift aliases for the generated DTOs that correspond to the github.com/getarcaneapp/arcane/types go package and the Arcane API.
let user: User
let container: ContainerSummary
let image: ImageSummary
let env: Environment
let volume: Volume
let webhook: WebhookSummaryThese are aliases to the generated OpenAPI schemas, not hand-written approximations, so fields stay aligned with the backend spec.
Use the hand-written facade for common SDK workflows:
let containers = try await client.containers.list()Drop to the generated client when you need an endpoint that does not have a facade wrapper yet:
let generated = client.generated
let response = try await generated.listContainers(
.init(path: .init(id: "0"))
)You can also add the ArcaneAPI product directly in Xcode if you want to work against only the generated OpenAPI module.
The checked-in spec is generated from the sibling Arcane repo:
Scripts/update-spec.shThe backend JSON path currently emits OpenAPI 3.1 even when --downgrade is passed, so the script intentionally asks the backend for downgraded YAML and converts it to JSON. It then regenerates the static Swift sources in Sources/ArcaneAPI.
Maintainers need swift-openapi-generator on PATH to run the script:
mint install apple/swift-openapi-generatorSpec/mobile.proto is a checked-in copy of the backend's mobile pairing proto. To regenerate Swift sources after updating it:
Scripts/generate-grpc.shMaintainers need protoc plus the Swift code generators on PATH:
brew install protobuf
mint install apple/swift-protobuf
mint install grpc/grpc-swift-protobufThe generated files are written to Sources/ArcaneGRPC/Generated/ and committed alongside the proto. App consumers do not need protoc installed.
swift build
swift testIntegration tests are skipped unless ARCANE_TEST_URL is set.
Install SwiftLint:
brew install swiftlintRun it from the repository root:
swiftlint lintAuto-correct safe style fixes:
swiftlint --fix