Skip to main content
Available from UI Kit v5.1.22. This feature requires CometChatUIKitSwift v5.1.22 or later, which depends on CometChatSDK v4.1.9.

Overview

Thread subscription gives users Slack-style control over thread noise: they can subscribe to a thread to be notified about its replies, or unsubscribe from one to mute it. Users are automatically subscribed when they start a thread, reply in one, or are @-mentioned in one — subscribing explicitly is how they opt in to a conversation they haven’t participated in yet. The UI Kit ships the toggle as a Subscribe to thread / Unsubscribe from thread option in the message action sheet, and broadcasts every change on the event bus so any control you host elsewhere — such as a button in your thread screen’s title bar — stays in sync.

Prerequisites

  • Threaded messages working in your app — see Threaded Messages.
  • CometChat UI Kit for iOS v5.1.22 or later, with Chat SDK v4.1.9 or later.

The Surfaces

Thread subscription surfaces in two places: the message action sheet on CometChatMessageList, and a bell in the thread screen’s navigation bar, rendered by CometChatMessageHeader. Each can be hidden per instance with hideThreadSubscriptionOption and hideThreadSubscriptionButton respectively.

Turning the Feature Off

Thread subscription is on by default — there is nothing to switch on. To remove it from your app entirely, close the gate:
With the gate closed neither surface renders and no subscription request is ever made, whatever the per-instance hideThreadSubscription* flags say. The two are ANDed: the gate decides whether the feature exists in your app at all, and the per-instance flags remove a surface from one screen. CometChatThreadSubscriptionConfig is a plain process-wide switch, not an init-time setting — you can flip it at any point, before or after CometChatUIKit.init, and read it back with isEnabled().
This is the only control that will ever exist for the feature. Unlike pin and save, thread subscription has no dashboard flag and no app setting, so nothing on the server can switch it on or off. The other CometChat platforms work the same way: Android uses CometChatThreadSubscriptionConfig.setEnabled(false) and React Native ThreadSubscriptionConfig.setEnabled(false).
Closing the gate hides the controls but does not stop subscriptions. Users are still subscribed automatically by starting a thread, replying, or being @-mentioned, and still receive thread notifications — they simply have no way to change it in your app. Suppressing the notifications themselves is a notification-settings concern, not a UI Kit one.

Surface 1: The Message Action Sheet Option

CometChatMessageList adds a Subscribe to thread / Unsubscribe from thread option to the long-press action sheet. The label and icon reflect the current state, read synchronously from the SDK when the sheet is built. The option appears only on parent messages — never on a reply inside a thread:
A subscription is always rooted at the thread’s parent message. Offering the option on a reply would create a thread row the user can never open, so the kit hides it there entirely. It is not gated on reply count — subscribing to a message with no replies yet is the point.
Thread subscription is offered in one-on-one conversations as well as groups — there is no receiver-type check. Subscribing applies to a 1-1 thread, and unsubscribing genuinely suppresses its notifications.
To hide the option while keeping the rest of the feature:
To replace the kit’s behavior with your own, supply an onItemClick on a custom option with the id MessageOptionConstants.threadSubscription — the kit calls your handler instead of its own.

Surface 2: The Bell in the Navigation Bar

CometChatMessageHeader renders a subscribe/unsubscribe bell in its trailing area. Set parentMessage to put the header in thread mode — the bell renders only then, so a conversation header is unaffected. As with the action-sheet option, it renders in one-on-one threads as well as groups. This is the bell to use. Every CometChat platform places the subscription bell in the thread screen’s top bar, not in the reply-count row beneath it — on iOS, putting CometChatMessageHeader in thread mode is how you get it there.
Host it as the thread screen’s navigation bar — pin it to the safe-area top and hide the system bar, exactly as a conversation screen does:
CometChatThreadedMessageHeader carries a fallback bell on its reply-count bar, so a thread screen with no top bar still has the control. A screen that renders both components should hide it, leaving the top-bar bell as the only one:
The bell tracks state on its own: it reads the current subscription state from the SDK, flips optimistically on tap, reverts if the request fails, toasts in both directions, and emits ccThreadSubscriptionChanged on success. You do not wire any of that up. If your screen draws a subscription control of its own in the navigation bar, suppress the kit’s:
The bell needs parentMessage, on a parent whose message has been sent. Without it a conversation header renders nothing — that is deliberate, so a thread control can never appear on a non-thread screen.

Cross-Surface Sync

Both surfaces observe the UI Kit event bus, so toggling in one place updates the other without a refetch. After a successful toggle the kit emits:
Both header components observe this themselves, so the bell stays correct when the user toggles from the action sheet — no wiring needed. Conform to CometChatThreadEventListener only to keep a control of your own in step:
Thread listeners are keyed by id, and registering a duplicate id evicts the previous listener. Use a distinct id per screen — the kit randomises its own for exactly this reason.
See Events for the full event reference.

Behavior

  • Optimistic with revert — the control flips instantly on tap, keeps one request in flight per thread, and reverts if the server rejects the change. An offline tap fails visibly and reverts; nothing is queued.
  • No event on failure — the kit emits ccThreadSubscriptionChanged only on success, so every surface keeps showing the state the server still holds.
  • Toasts in both directions — subscribing and unsubscribing each confirm with a toast, and both toggle sites use the same copy.
  • Unsubscribing is not sticky — replying again, or being @-mentioned, re-subscribes the user. The kit says so in the toast rather than letting the user discover it.
  • Unknown state renders as unsubscribed — a message whose subscription state hasn’t been learned yet (for example, one that just arrived in real time) shows the enabled subscribe control, never a spinner.

Copy and Localization

THREAD_SUBSCRIBED is a VoiceOver-only label for the subscribed state — it is not shown as visible text.
Override any of these in your own Localizable.strings — see Localize.

Notifications

Whether a subscribed thread actually produces a push notification is governed by the user’s notification preferences: the replies preference supports notifying only for threads the user is subscribed to (SUBSCRIBE_TO_SUBSCRIBED_THREADS). See Thread Subscription (SDK).

Next Steps & Further Reading