jvdvleuten

jvdvleuten

PhoenixNectar - Swift 6 client for Phoenix Channels

PhoenixNectar is a Swift client for Phoenix Channels, built from the ground up for Swift 6 strict concurrency.

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 (actors, async/await, and AsyncStream) rather than the JS-style callback API.

What it looks like

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

// Subscribe with AsyncStream
let posted = Event<ChatMessage>("message:posted")

for try await message in await channel.subscribe(to: posted) {
   print(message.body)
}

// Typed push with reply
let send = Push<ChatMessage, ChatMessage>("message:send")
let reply = try await channel.push(send, payload: ChatMessage(body: "hello"))
print(reply.body)

Features

  • Swift 6 strict concurrency — actor-owned runtime, no @unchecked Sendable workarounds
  • Push<Request, Response> and Event<T> for compile-time payload type safety
  • Auto reconnect, heartbeat, and channel rejoin
  • Auth token providers that re-evaluate on each reconnect
  • Connection state observation via AsyncStream
  • Binary channel support
  • iOS 16+, macOS 15+, tvOS 18+, watchOS 11+

Feedback welcome, especially from anyone running Phoenix Channels with iOS/macOS clients.

A demo project (demo iOS project with chat and image upload) and E2E tests are provided as well.

https://github.com/jvdvleuten/PhoenixNectar

Most Liked

_pk

_pk

This is awesome to see! I’m quite interested as I make heavy use of Phoenix Channels in iOS apps, and have been thinking of working up something like this.

SwiftPhoenixClient has been great, I’m grateful for it and have made a few contributions. But it would need a ton of work to adopt strict concurrency and I agree that starting from scratch is the better move.

I’ll try dropping this into a project and send some detailed feedback soon.

Where Next?

Popular in Announcing Top

KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36654 110
New
jakub-zawislak
Hi everyone, I’m coming from the Symfony (PHP) framework. I like Phoenix, but it has a one thing that was build much better in the Symfo...
New
Crowdhailer
Raxx is an alternative to Plug and is inspired by projects such as Rack(Ruby) and Ring(Clojure). 1.0-rc.1 is now available. To use it re...
New
anshuman23
Hello all, I have been working on my proposed project called Tensorflex as part of Google Summer of Code 2018.. Tensorflex can be used f...
New
mindok
What is ContEx? A pure Elixir server-side data plotting/charting library outputting SVG. It has nice barcharts in particular and works g...
New
mplatts
With HEEX released we decided to start a components library using Tailwind CSS - check it out here: Petal Components. We also have a boi...
New
wojtekmach
Hey everyone! Req is an HTTP client for Elixir that I’ve been working on for quite some time. There is already a lot of HTTP clients out...
New

Other popular topics Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement