Skip to main content

Publish and Subscribe

The Swift ADK provides a robust publish-subscribe system for real-time communication. This guide covers the core messaging patterns and channel management features.

Subscribe to channel

Channel subscription is the foundation of real-time communication in ART. When you subscribe to a channel, you establish a persistent connection that enables bidirectional messaging with automatic connection management, fallback protocols, and message buffering.

The subscription process in ART is asynchronous and involves several behind-the-scenes operations to ensure reliable connectivity:

// Basic subscription
let subscription = try await adk.subscribe(channel: "my-channel")

// Listen to specific events
subscription.emitter.on("message") { data in
print("Message:", data)
}

subscription.emitter.on("alert") { data in
print("Alert:", data)
}

The return type is BaseSubscription. For shared-object (CRDT) channels, downcast to LiveObjSubscription to access the CRDT API:

if let live = subscription as? LiveObjSubscription {
// CRDT-enabled channel: state(), query(), flush()
}

Channel namespaces

Channel namespaces provide a powerful way to organize and isolate communication streams within your application. Think of namespaces as folders that help you categorize channels logically, enabling better organization and access control.

Namespaces use the colon (:) separator to create hierarchical channel names:

// Basic format is channelName:namespace
let subscription = try await adk.subscribe(channel: "chat:general")

Push message into channel

Once subscribed to a channel, you can send messages to other subscribers using the push() method. Messages are delivered based on the channel type and targeting options you specify.

Send to all users

Broadcast messages to all subscribers of a channel:

// Define the message payload
let payload: [String: Any] = [
"content": "Hello from ART ADK!"
]

do {
try await subscription.push(
event: "message",
data: payload
)
print("Message pushed successfully")
} catch {
print("Failed to push message:", error)
}

Send to a list of users or a specific user

Target specific users for private messaging or selective broadcasting:

// Define the message payload
let payload: [String: Any] = [
"content": "Hello from ART ADK!"
]

// Optionally define specific target users within the channel
let targetUsers = ["username1", "username2"]

do {
try await subscription.push(
event: "message",
data: payload,
options: PushConfig(to: targetUsers) // Target specific recipients
)
print("Message acknowledged by ART")
} catch {
print("Failed to push message:", error)
}
  • event — the event name that subscribers will listen for
  • data — the message data (any JSON-serializable Map<String, dynamic>)
  • options — a PushConfig with the to list for target usernames
important

Targeted and Encrypted channels require exactly one recipient in the to list.

Listen to events

After subscribing to a channel, you need to set up event listeners to handle incoming messages. The Swift ADK provides flexible options for listening to messages based on your application needs.

Listen to all events

Receive all messages regardless of event type using the listen() method:

subscription.listen { data in
print("Event \(data["event"] ?? "")\(data["content"] ?? "")")
// Your logic to handle events
}

This is useful for logging all channel activity, generic message processing, debugging, and monitoring.

Listen to a particular event

Use emitter.on() to listen for a specific event within the subscribed channel. Unlike listen(), which captures everything, emitter.on() filters messages and triggers the callback only when the defined event occurs:

subscription.emitter.on("event") { data in
print("Received event:", data)
// Your logic to handle the event
}

To stop listening to a specific event:

subscription.emitter.off('event');

Unsubscribe from channel

Clean up subscriptions to free resources and stop receiving messages when they're no longer needed. Proper unsubscription ensures your application remains performant and doesn't waste resources on unused connections:

// Unsubscribe from channel
await subscription.unsubscribe();

print("Successfully unsubscribed from channel")