Promo Image
  • Native Swift SDK for iOS, macOS, tvOS, and watchOS
  • @Actor property wrapper for declarative SwiftUI integration
  • Typed async/await actions and AsyncStream events
  • Automatic reconnection and connection state management

Example SwiftUI Application

A simple counter app with realtime updates.

import RivetKitSwiftUI
import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            CounterView()
                // Configure once at app root
                .rivetKit(endpoint: "https://my-namespace:[email protected]")
        }
    }
}

struct CounterView: View {
    // Declare actor connection with property wrapper
    @Actor("counter", key: ["my-counter"]) private var counter
    @State private var count = 0

    var body: some View {
        VStack {
            Text("\(count)")

            Button("Increment") {
                // Fire-and-forget action
                counter.send("increment", 1)
            }
            .disabled(!counter.isConnected)
        }
        .task {
            // Async action with typed response
            count = (try? await counter.action("getCount")) ?? 0
        }
        // Subscribe to realtime events
        .onActorEvent(counter, "newCount") { (newCount: Int) in
            count = newCount
        }
        // Handle connection errors
        .onActorError(counter) { error in
            print("\(error.group).\(error.code): \(error.message)")
        }
    }
}

Documentation & Source code

Example CLI Application

Connect to actors from command-line tools or backend services.

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:3000/api/rivet")
let client = RivetKitClient(config: config)

// Get or create an actor by name and key
let handle = client.getOrCreate("counter", ["my-counter"])

// Stateless action call (HTTP)
let count: Int = try await handle.action("getCount")

// Stateful connection for realtime events (WebSocket)
let conn = handle.connect()

// Subscribe to events using AsyncStream
let eventTask = Task {
    for await newCount in await conn.events("newCount", as: Int.self) {
        print("Count updated: \(newCount)")
    }
}

// Action over persistent connection
_ = try await conn.action("increment", 1, as: Int.self)

// Cleanup
eventTask.cancel()
await conn.dispose()
await client.dispose()

Documentation & Source code