CXoneChat

@MainActor
public final class CXoneChat : ChatProvider

Entry point of the CXone Chat SDK and the canonical conformer of ChatProvider.

Construct one CXoneChat instance at app start with init() and hold the reference for the lifetime of your chat experience. Pass it through your app as the protocol type ChatProvider to keep code testable. Use the provider properties (connection, customer, threads, analytics, customerCustomFields, proactiveAction) to drive the SDK; subscribe to events() for state changes, thread updates, and errors.

CXoneChat is @MainActor-isolated — call sites from background contexts must hop to the main actor (see the ChatProvider protocol docs and the Migration Guide for details).

Important

Earlier SDK versions exposed CXoneChat.shared and CXoneChatDelegate. Both are removed. See migration-from-singleton.md for the upgrade walkthrough.

Public properties

  • The handler for the logs occured in CXoneChat.

    Declaration

    Swift

    @MainActor
    public static var logWriter: LogWriter? { get set }
  • Current chat state of the SDK

    The state defines if the SDK is prepared for API services (analytics), connected for chat features or if it needs to be prepared or connected for proper usage.

    Declaration

    Swift

    @MainActor
    public var state: ChatState { get }
  • Chat mode defining available functionality.

    Declaration

    Swift

    @MainActor
    public var mode: ChatMode { get }

API providers

Init

  • Creates a new CXoneChat instance with default SDK-internal services (keychain-backed token storage, UserDefaults-backed visitor state, real WebSocket transport).

    Construct once at app start and hold the reference for the lifetime of the chat experience — see CXoneChat for the ownership and lifecycle rules.

    Declaration

    Swift

    @MainActor
    public convenience init()

Public methods

  • Returns a new AsyncStream of all SDK events.

    Each call produces an independent stream — multiple components in your app can each subscribe and all receive every event. There is no fan-in or de-duplication across subscribers; cancelling one task does not affect the others.

    let observation = Task { [chatProvider] in
        for await event in chatProvider.events() {
            switch event {
            case .threadUpdated(let thread): /* handle */ break
            case .error(let error): /* surface to user */ break
            default: break
            }
        }
    }
    // Later, to stop observing:
    observation.cancel()
    

    Lifecycle

    • The stream never finishes with an error. SDK errors arrive as the error(_:) case — handle it as you would any business-level error (surface to the user, log, retry, etc.).
    • Calling signOut() finishes every active stream cleanly — each for await loop exits normally with no error.
    • To stop observing without signing out, cancel the wrapping Task.
    • Each stream buffers at most 64 events; if the consuming Task falls behind, the oldest buffered events are silently dropped. Keep the for await body lightweight or hand off heavy work via Task { }.

    Declaration

    Swift

    @MainActor
    func events() -> AsyncStream<ChatEvent>
  • Signs the customer out, disconnects from the CXone service, and clears the session.

    Calling this method:

    1. Disconnects the WebSocket cleanly (does not emit unexpectedDisconnect).
    2. Purges the SDK’s keychain entries and UserDefaults state.
    3. Discards the in-memory session state — the loaded threads and their messages, the customer and per-contact custom fields, the channel configuration, and the brand, channel and environment the session was prepared against. state returns to initial.
    4. Finishes every active events() stream — observers see their for await loop exit normally.

    The device token and any listener registered with setTokenDelegateListener(_:) are deliberately kept: both belong to the application rather than to the chat session, so they stay valid for the next one.

    The instance remains alive and reusable after signOut(). You can call prepare(environment:brandId:channelId:) and connect() again to start a new session with fresh credentials. If you prefer a clean slate, discard this instance and construct a new CXoneChat.

    Declaration

    Swift

    @MainActor
    func signOut()