Skip to content

getarcaneapp/libarcane-swift

Repository files navigation

Arcane Swift

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 from Spec/openapi.json with Apple's swift-openapi-generator and 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.v1 proto). 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.

Quickstart

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)
}

Generated API

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: WebhookSummary

These 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.

Spec Sync

The checked-in spec is generated from the sibling Arcane repo:

Scripts/update-spec.sh

The 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-generator

gRPC Sync

Spec/mobile.proto is a checked-in copy of the backend's mobile pairing proto. To regenerate Swift sources after updating it:

Scripts/generate-grpc.sh

Maintainers need protoc plus the Swift code generators on PATH:

brew install protobuf
mint install apple/swift-protobuf
mint install grpc/grpc-swift-protobuf

The generated files are written to Sources/ArcaneGRPC/Generated/ and committed alongside the proto. App consumers do not need protoc installed.

Development

swift build
swift test

Integration tests are skipped unless ARCANE_TEST_URL is set.

Linting

Install SwiftLint:

brew install swiftlint

Run it from the repository root:

swiftlint lint

Auto-correct safe style fixes:

swiftlint --fix

About

Arcane API Client built in Swift

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors