Available from Chat SDK v4.1.9. These APIs require
CometChatSDK v4.1.9 or later.Thread subscription builds on Threaded Messages. A thread is identified by the ID of its parent message — there is no separate thread ID.Subscribe to a Thread
To subscribe to a thread, use thesubscribeToThread method with the ID of the thread’s parent message. The call is idempotent — subscribing to a thread the user is already subscribed to succeeds silently. Subscribing to a message with zero replies is allowed; the user will be notified when the first reply arrives.
- Swift
Unsubscribe from a Thread
To unsubscribe from a thread, use theunsubscribeFromThread method. This too is idempotent — unsubscribing from a thread the user is not subscribed to succeeds silently.
- Swift
Read the Subscription State
Every fetched message carries the logged-in user’s subscription state for its own thread onBaseMessage.threadSubscribed. It arrives with the message fetch, so rendering a subscribe control needs no extra network call and no separate state cache.
- Swift
Bool, read it only off a message you actually fetched:
The property also has a setter, which is local only and performs no network call. It exists so you can align message objects you already hold with a truth you have just established — for example after a successful
subscribeToThread:
- Swift
subscribeToThread / unsubscribeFromThread.
Fetch the Threads a User Participates In
To build a thread inbox — one row per thread the user is part of — create aThreadsRequest using the ThreadsRequestBuilder. The list is the union of threads the user started, replied in, was mentioned in, or explicitly subscribed to. Every returned row is, by definition, a thread the user is subscribed to: participation is subscription, and unsubscribing removes the row.
- Swift
fetchNext repeatedly to page forward; hasMore() tells you whether more pages exist. A ThreadsRequest is single-use and forward-only — there is no fetchPrevious. To refresh the list from the top, build a new request from the builder and replace your list with its results.
Paging is internally keyed on a compound (updatedAt, id) cursor, matching the JS and Android SDKs. updatedAt alone is second-granular, so threads updated within the same second could not be separated by it and a page boundary could only step past the whole second — skipping every unseen row in it. Carrying the boundary row’s id makes the cursor address one exact row, so a block of same-second threads spills across pages instead of being dropped. You do not set this yourself; it matters only if you were previously working around duplicated or skipped rows.
The MessageThread Model
Each row is aMessageThread:
The list starts empty for every user when the feature launches — it fills up as users reply, get mentioned, and subscribe to threads. There is no historical backfill.
Offline support
With offline support enabled (SDK 4.2.0 or later),fetchNext on a ThreadsRequest has an overload that delivers a cached page first (onCachedThreads, even when empty) and then the server list (onServerThreads). Offline, it ends with onError, code ERROR_INTERNET_UNAVAILABLE, after the cached page.
- With
set(participatedByMe: true)(the default),onCachedThreadsholds the threads you take part in that the cache already knows about, in the same order.set(uid:)andset(guid:)scope that list to one conversation. - With
set(participatedByMe: false), the cached page is always empty.
Keeping Your UI in Sync
The SDK does not expose a thread listener or thread-subscription callbacks, and it keeps no subscription state of its own beyond the flag on each message. The server’s flag on the message is the single source of truth. With offline support on, the flag is also cached with the message, so a cached read returns the last known value and the server read then updates it. Keep your UI in step yourself:- After your own subscribe/unsubscribe — update the message you hold by setting
threadSubscribedin the success callback (local only, no network). This is the normal case and needs nothing else. - On the next fetch —
threadSubscribedarrives with every fetched message, so a refresh always corrects the state. - For new replies — use the regular message listener (
onTextMessageReceivedand friends) and checkparentMessageIdto spot a threaded reply.
A subscribe or unsubscribe performed on the user’s other device produces no real-time event on this one. The state self-corrects on the next message fetch, so refresh when the app returns to the foreground.
Notification Preferences
The notification preference for replies gains a new value so users can be notified only for threads they are subscribed to:SUBSCRIBE_TO_SUBSCRIBED_THREADS in the replies options.
Quoted replies are a separate preference
A quoted reply (a reply to one specific message) and a threaded reply (a message posted into a thread) are configured independently, through two different enums. They are not interchangeable — the raw value4 means something different on each.
- Swift