Skip to content

Swift (iOS, macOS) API

Generated from the source and its doc comments (sdk/client-swift/Sources/AgentIM/AgentIMClient.swift).

Package.swift
.package(url: "https://github.com/wmkrfjnwvb-svg/agentim-swift", from: "0.1.0")
public struct ClientOptions

How the client starts: the server address, this device’s id, the cache, the token provider and how it names itself.

public var url: String

https://chat.example.com.

public var deviceId: String

This device’s id, the same every run (1..64 of A-Z a-z 0-9 _ -).

public var storeDir: String?

Where the cache lives; nil keeps it in memory.

public var deviceName: String?

A name for this device in the user’s device list, like “Maya’s iPhone”.

public var platform: String?

The platform reported to the server (ios, android, windows…), for the device list and push.

public var tokenProvider: @Sendable () async throws -> String

A client token from your backend; throw TokenRefused to stop.

public var clientName = "agentim-swift"

This app’s name, sent to the server with each connection (for diagnostics and minimum-version rules).

public var clientVersion = "0.1.0"

This app’s version, sent with clientName.

public var commandTimeout: TimeInterval = 60

How long a command waits for its answer before failing with timeout. In seconds.

public init(url: String, deviceId: String, storeDir: String? = nil, deviceName: String? = nil, platform: String? = nil,

Options with the required server address, device id and token provider; the rest are optional.

public struct TokenRefused: Error

Thrown by a token provider when the backend refuses the user.

public init() {}

Throw TokenRefused() from the token provider.

public struct AgentIMError: Error, CustomStringConvertible

The server’s code (forbidden, not_found, conflict, bad_request, blocked, rate_limited…) or the client’s (disconnected, timeout, closed…); unknown codes pass through as they are.

public let code: String

The error code: the server’s (forbidden, not_found, conflict, bad_request, …) or the client’s (disconnected, timeout, closed, unauthenticated).

public let message: String

A human-readable explanation, for logs (not for showing to users).

public let retryable: Bool

Whether the same request may work later.

public let retryAfterMs: Int64?

How long the server asked to wait before trying again.

public init(code: String, message: String, retryable: Bool = false, retryAfterMs: Int64? = nil)

An error with its code; used by the client and by tests.

public var description: String { "\(code): \(message)" }

code: message.

public struct Connection: Equatable

The connection state and why: state is closed, connecting, connected, disconnected, suspended or failed.

public let state: String

closed, connecting, connected, disconnected, suspended or failed.

public let reason: String?

Why it is not connected (an error code), when it is not.

public let retryAt: Int64?

When the next reconnect attempt is due (Unix ms), while waiting to reconnect.

public struct Message

One message as shown; raw has every field the core gives.

public let key: String

The stable local key: the same while the message goes from sending to sent, for list identity.

public let msgId: String?

The server’s id, once sent.

public let clientMsgId: String?

The id this device gave the message, for retries.

public let content: String

The text (for a streaming reply, what has arrived so far).

public let status: String

sent, sending or failed.

public let state: String?

The server state: normal, edited, recalled…

public let senderType: String?

human, agent, system: agent messages must show the AI mark (EU AI Act art. 50).

public let order: Double

The sort position in the list.

public let raw: JSONObject

Every field as the core sent it.

public struct Conversation

One conversation in the list.

public let convId: String

The conversation id.

public let raw: JSONObject

Every field as the core sent it.

public final class Messages

One conversation’s messages as shown, oldest first.

public let convId: String

The conversation these messages belong to.

public func loadOlder() async throws -> Bool

The page before the oldest shown: the cache first, then the server. False at the start.

public func jumpTo(_ seq: Int64) async throws

A page around a message (it stays loaded).

public final class AgentIMClient: @unchecked Sendable

The AgentIM client for one account on one device: keeps the connection, syncs, sends the offline queue in order, keeps the local cache, and turns everything into observable state.

public static var version: String { String(cString: agentim_version()) }

The version of the native core.

public init(_ o: ClientOptions, queue: DispatchQueue = .main) throws

queue: where state changes, events and replies are handled, in order (main by default).

public func command(_ cmd: JSONObject) async throws -> Any?

Any core command (["cmd": …]); returns its result.

public func on(_ type: String, _ fn: @escaping (JSONObject) -> Void) -> Subscription

Events: operation, side, signal, reset, storage, event, read, mute (and the ones above). Handled on the client’s queue; call cancel() on the result to stop.

public func setNetwork(online: Bool)

The platform’s network: call on every change (NWPathMonitor).

public func setForeground(_ foreground: Bool)

The app came to the foreground or went to the background (scenePhase).

public func messages(_ convId: String) -> Messages

The conversation’s messages, kept up to date. Call on the client’s queue (main).

public func connect() async throws { try await command(["cmd": "connect"]) }

Connects and keeps connecting: reconnects with backoff when the network or the server goes, syncs what it missed, sends the offline queue.

public func disconnect() async throws { try await command(["cmd": "close"]) }

Closes the connection (the client stays usable; close() frees it).

public func logout() async throws { try await command(["cmd": "logout"]) }

Logs out here: closes and wipes the cache and the queue (GDPR).

public func send(_ convId: String, _ text: String, clientMsgId: String? = nil, replyTo: String? = nil, threadId: String? = nil, alsoInConv: Bool = false) async throws -> JSONObject

Returns client_msg_id and key once the message is queued and shown.

public func sendFile(_ convId: String, path: String, name: String? = nil, mime: String? = nil, caption: String? = nil, replyTo: String? = nil, keepMetadata: Bool = false) async throws -> JSONObject

Sends a file or a photo from a path: shown at once as uploading, sent when it is up. A photo loses its EXIF and GPS (unless keepMetadata) and gets a 320-pixel thumbnail (docs/en/design/messaging.md).

public func fileUrl(_ convId: String, fileId: String, variant: String = "original") async throws -> JSONObject

A link (valid a few minutes) to read a file: original or thumb.

public func edit(_ convId: String, msgId: String, _ text: String) async throws

Edits one of my messages (by msgId, or by clientMsgId while it is still queued); the change shows at once.

public func recall(_ convId: String, msgId: String) async throws

Recalls one of my messages for everyone; a message still in the queue is simply not sent.

public func read(_ convId: String, seq: Int64? = nil) async throws

Marks the conversation read up to seq (default: the newest) on all my devices.

public func retry(_ convId: String, clientMsgId: String) async throws

Sends a failed message again (the same client_msg_id, so it is never doubled).

public func discard(_ convId: String, clientMsgId: String) async throws

Drops a failed or waiting message from the queue.

public func react(_ convId: String, msgId: String, key: String) async throws -> JSONObject

Adds a reaction (one emoji, or one of the app’s :names:); adding it twice changes nothing.

public func unreact(_ convId: String, msgId: String, key: String) async throws -> JSONObject

Removes my reaction; removing one that is not there changes nothing.

public func pin(_ convId: String, msgId: String) async throws -> JSONObject

Pins a message to the conversation; pinning it again changes nothing.

public func unpin(_ convId: String, msgId: String) async throws -> JSONObject

Unpins a message.

public func listPins(_ convId: String) async throws -> JSONObject

The conversation’s pinned messages, latest pin first.

public func pullThread(_ convId: String, threadId: String, afterSeq: Int64 = 0) async throws -> JSONObject

A thread’s root and its replies after afterSeq.

public func listThreads(convId: String? = nil) async throws -> JSONObject

The threads I follow (in one conversation, or all), latest reply first, with unread counts.

public func readThread(_ convId: String, threadId: String, seq: Int64) async throws

Marks a thread read up to seq on all my devices.

public func followThread(_ convId: String, threadId: String, follow: Bool = true) async throws

Follows a thread (its replies notify me) or stops following it.

public func msgSummary(_ convId: String, msgIds: [String]) async throws -> JSONObject

The thread summary, reactions and pin of up to 100 messages (for messages loaded from history).

public func call(_ op: String, _ args: JSONObject = [:]) async throws -> Any?

A request that needs the server now (approvals, decisions, queries).

public func debugState() async throws -> Any? { try await command(["cmd": "debug_state"]) }

Everything that helps report a problem: the connection, positions, the queue and recent failures.

public func close()

Stops the client; no event arrives after it returns. Waiting calls fail with closed. Not from the SDK’s own thread.

public final class Subscription

A subscription to client events; cancel it to stop.

public func cancel()

Stops the subscription; calling it again does nothing.