I'd like to share PhoenixNectar, a Swift 6 client for Phoenix Channels, the real-time WebSocket layer of the Phoenix web framework (Elixir).
If you're building an iOS or macOS app that talks to a Phoenix backend over WebSockets, this is for you. It's designed around Swift's modern concurrency model from the start (actors, async/await, and AsyncStream) rather than wrapping a callback-based API.
It builds on the great work of SwiftPhoenixClient by David Stump and Daniel Rees, which has been the go-to Swift client for years. PhoenixNectar takes a different approach by embracing Swift’s modern concurrency model rather than the JS-style callback API.
Quick example
import PhoenixNectar
struct ChatMessage: Codable, Sendable {
let body: String
}
let client = try Socket(endpoint: "wss://api.example.com/socket")
try await client.connect()
let channel = try await client.joinChannel("room:lobby")
// Inbound events as an AsyncStream
let posted = Event<ChatMessage>("message:posted")
for try await message in await channel.subscribe(to: posted) {
print(message.body)
}
// Typed push with an awaited reply
let send = Push<ChatMessage, ChatMessage>("message:send")
let reply = try await channel.push(send, payload: ChatMessage(body: "hello"))
What makes it tick
-
Actor-owned runtime — all socket and channel state lives inside actors, so it's fully safe under Swift 6 strict concurrency with no
@unchecked Sendableworkarounds -
Typed payloads —
Push<Request, Response>andEvent<T>give you compile-time safety on your channel messages viaCodable -
AsyncStream subscriptions — observe channel events and connection state changes with
for awaitloops -
Auto reconnect and rejoin — transport loss, heartbeat timeouts, and server closes all trigger automatic reconnect with configurable backoff; joined channels are rejoined automatically
-
Auth token refresh —
authTokenProviderandconnectParamsProviderclosures are re-evaluated on every reconnect
Supports iOS 16+, macOS 15+, tvOS 18+, watchOS 11+. Available as a Swift package.
Feedback and contributions welcome!