Home
/
Chat
/
iOS

Message threading

Message threading is a feature that allows users to ask questions, give feedback or add context to a specific message without disrupting the conversation flow. A message thread refers to a collection of messages grouped together, consisting of a parent message and its replies. It can have the following elements:

  • A message can have a thread of replies.
  • A message that has a thread of replies is a parent message.
  • A parent message and its threaded replies are collectively called a message thread.
  • Every message within a thread, whether it's parent or reply, is a threaded message.
  • A message that doesn't have any replies is an unthreaded message.


Benefits

Message threading can be widely used to help conversations flow smoothly while keeping users engaged. Message replies in a thread are common among popular messaging platforms, such as Slack and iMessage.

  • Conversation flow: Without message threading, it's hard to specify which message a channel member is responding to. Users would have to explain the context of their response, potentially confusing other channel members and distracting them from reading new messages. Message threads can help everyone stay engaged and carry on their conversation without any interferences.

  • In-depth discussions: By allowing users to reply to each other's messages in a thread, they can have more in-depth conversations on one topic. They're able to ask follow-up questions or provide more detailed explanations to a specific message without interrupting others in the channel. Message threads can encourage users to start topic-specific discussions separate from the main channel conversation.


Limitations

Refer to the following limitations before using the message threading feature:

  • Message threading doesn't integrate with SyncManager.
  • SDK only supports 1-depth threads, meaning you can only add reply messages to non-reply messages. You can't add a reply to a reply message.
  • You can only reply to text and file messages, not admin messages. However, you can add admin type messages as a reply to another message.

List messages along with their replies

You can retrieve messages and their replies.

Load channel messages

The loadPreviousMessagesWithLimit:reverse:completionHandler: method of a SBDPreviousMessageListQuery instance returns a list of SBDBaseMessage objects. With this method, you can retrieve previous messages in a specific channel. To include the replies of the target messages in the results, you need to change the value of the includeReplies property in the SBDPreviousMessageListQuery instance.

SBDPreviousMessageListQuery

The following table lists the properties of this class.

Property nameTypeDescription

includeReplies

bool

Determines whether to include replies in the results.

includeThreadInfo

bool

Determines whether to include the thread information of the messages in the results when the results contain parent messages.

includeParentMessageText

bool

Determines whether to include the parent message text in the results when the retrieved messages are replies in a thread. If the type of the parent message is SBDUserMessage, the value is a message property. If it is a SBDFileMessage, the value is the name of the uploaded file.

Objective-C
Swift
Light Color Skin
Copy
SBDPreviousMessageListQuery *listQuery = [channel createPreviousMessageListQuery];
listQuery.includeReplies = INCLUDE_REPLIES;
listQuery.includeThreadInfo = INCLUDE_THREAD_INFO;
listQuery.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT;
Light Color Skin
Copy
let listQuery = channel!.createPreviousMessageListQuery()
listQuery!.includeReplies = INCLUDE_REPLIES
listQuery!.includeThreadInfo = INCLUDE_THREAD_INFO
listQuery!.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT

loadPreviousMessagesWithLimit:reverse:completionHandler:

The following table lists the parameters that this method supports.

Parameter nameDescription

LIMIT

Type: NSInteger

Specifies the number of results to return per call. Acceptable values are 1 to 100, inclusive. The recommended value for this parameter is 30.

REVERSE

Type: BOOL

Determines whether to sort the retrieved messages in reverse order. If false, the results are in ascending order.

Objective-C
Swift
Light Color Skin
Copy
// Retrieving previous messages.
[listQuery loadPreviousMessagesWithLimit:LIMIT reverse:REVERSE completionHandler:^(NSArray * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
// Retrieving previous messages.
listQuery?.loadPreviousMessages(withLimit: LIMIT, reverse: REVERSE, completionHandler: { (messages, error) in
    if error != nil {
        // Handle error.
    }

    ...
})

Load messages by timestamp or message ID

The getMessagesByTimestamp:params:completionHandler: and getMessagesByMessageId:params:completionHandler: methods of a SBDBaseChannel instance return a list of SBDBaseMessage objects. By using these methods, you can retrieve messages in a specific channel according to a SBDMessageListParams object.

SBDMessageListParams

The following table lists the properties of this class.

Property nameDescription

previousResultSize

Type: NSInteger

Specifies the number of messages to retrieve that were sent before the specified timestamp or message ID.

nextResultSize

Type: NSInteger

Specifies the number of messages to retrieve that were sent after the specified timestamp or message ID.

isInclusive

Type: BOOL

Determines whether to include the messages with the matching timestamp or message ID in the results.

reverse

Type: BOOL

Determines whether to sort the retrieved messages in reverse order. If false, the results are in ascending order.

includeReplies

Type: BOOL

Determines whether to include replies in the results.

includeThreadInfo

Type: BOOL

Determines whether to include the thread information of the messages in the results when the results contain parent messages.

includeParentMessageText

Type: BOOL

Determines whether to include the parent message text in the results when the messages are replies in a thread. If the type of the parent message is SBDUserMessage, the value is a message property. If it is SBDFileMessage, the value is the name of the uploaded file.

Objective-C
Swift
Light Color Skin
Copy
SBDMessageListParams *params = [[SBDMessageListParams alloc] init];
params.previousResultSize = PREV_RESULT_SIZE;
params.nextResultSize = NEXT_RESULT_SIZE;
params.isInclusive = INCLUSIVE;
params.reverse = REVERSE;
params.includeReplies = INCLUDE_REPLIES;
params.includeThreadInfo = INCLUDE_THREAD_INFO;
params.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT;
Light Color Skin
Copy
let params = SBDMessageListParams()
params.previousResultSize = PREV_RESULT_SIZE
params.nextResultSize = NEXT_RESULT_SIZE
params.isInclusive = INCLUSIVE
params.reverse = REVERSE
params.includeReplies = INCLUDE_REPLIES
params.includeThreadInfo = INCLUDE_THREAD_INFO
params.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT

By timestamp

By using the getMessagesByTimestamp:params:completionHandler: method, you can retrieve a set number of messages of previous and next messages on both sides of a specific timestamp in a channel.

Objective-C
Swift
Light Color Skin
Copy
[channel getMessagesByTimestamp:TIMESTAMP params:params completionHandler:^(NSArray * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A list of previous and next messages on both sides of a specified timestamp is successfully retrieved.
    // Through the "messages" parameter of the callback method,
    // you can access and display the data of each message from the result list that Sendbird server has passed to the callback method.
    [self.messages addObjectsFromArray:messages];
    ...
}];
Light Color Skin
Copy
channel?.getMessagesByTimestamp(TIMESTAMP, params: params, completionHandler: { (messages, error) in
    if error != nil {
        // Handle error.
    }

    // A list of previous and next messages on both sides of a specified timestamp is successfully retrieved.
    // Through the "messages" parameter of the callback method,
    // you can access and display the data of each message from the result list that Sendbird server has passed to the callback method.
    self.messages += messages!
    ...
})

List of arguments

ArgumentTypeDescription

TIMESTAMP

long

Specifies the timestamp to be the reference point for messages to retrieve, in Unix milliseconds format. Messages sent before or after the timestamp can be retrieved.

By message ID

By using the getMessagesByMessageId:params:completionHandler: method, you can retrieve a set number of previous and next messages on both sides of a specific message ID in a channel.

Objective-C
Swift
Light Color Skin
Copy
[channel getMessagesByMessageId:MESSAGE_ID params:params completionHandler:^(NSArray * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A list of previous and next messages on both sides of a specified message ID is successfully retrieved.
    // Through the "messages" parameter of the callback method,
    // you can access and display the data of each message from the result list that Sendbird server has passed to the callback method.
    [self.messages addObjectsFromArray:messages];
    ...
}];
Light Color Skin
Copy
channel?.getMessagesByMessageId(MESSAGE_ID, params: params, completionHandler: { (messages, error) in
    if error != nil {
        // Handle error.
    }

    // A list of previous and next messages on both sides of a specified message ID is successfully retrieved.
    // Through the "messages" parameter of the callback method,
    // you can access and display the data of each message from the result list that Sendbird server has passed to the callback method.
    self.messages += messages!
    ...
})

List of arguments

ArgumentTypeDescription

MESSAGE_ID

long long

Specifies the message ID to be the reference point for messages to retrieve. Messages sent before or after the message with the matching message ID can be retrieved.


List replies of a parent message

You can retrieve replies of a parent message if you can specify the parent message like the following. First, create an SBDThreadedMessageListParams object and set properties related to the thread where the target replies belong to.

Objective-C
Swift
Light Color Skin
Copy
SBDThreadedMessageListParams *params = [[SBDThreadedMessageListParams alloc] init];
params.previousResultSize = PREV_RESULT_SIZE;
params.nextResultSize = NEXT_RESULT_SIZE;
params.isInclusive = INCLUSIVE;
params.reverse = REVERSE;
params.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT;
Light Color Skin
Copy
let params = SBDThreadedMessageListParams()
params.previousResultSize = PREV_RESULT_SIZE
params.nextResultSize = NEXT_RESULT_SIZE
params.isInclusive = INCLUSIVE
params.reverse = REVERSE
params.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT

SBDThreadedMessageListParams

PropertyDescription

previousResultSize

Type: NSInteger

Specifies the number of messages to retrieve that were sent before the specified timestamp.

nextResultSize

Type: NSInteger

Specifies the number of messages to retrieve that were sent after the specified timestamp.

isInclusive

Type: BOOL

Determines whether to include the messages with the matching timestamp in the results.

reverse

Type: BOOL

Determines whether to sort the retrieved messages in reverse order. If false, the results are in ascending order.

includeParentMessageText

Type: BOOL

Determines whether to include the parent message text in the results when the messages are replies in a thread. If the type of the parent message is SBDUserMessage, the value is a message property. If it is SBDFileMessage, the value is the name of the uploaded file.

With the timestamp of the parent message, you can retrieve its replies by passing an SBDThreadedMessageListParams object as an argument to the parameter in the getThreadedMessagesByTimestamp:params:completionHandler: method.

Objective-C
Swift
Light Color Skin
Copy
[parentMessage getThreadedMessagesByTimestamp:TIMESTAMP params:params completionHandler:^(SBDBaseMessage * _Nullable parentMessage, NSArray * _Nullable threadedReplies, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A list of replies of the specified parent message timestamp is successfully retrieved.
    // Through the "threadedReplies" parameter of the callback method,
    // you can access and display the data of each message from the result list that Sendbird server has passed to the callback method.
    ...
}];
Light Color Skin
Copy
parentMessage.getThreadedMessages(byTimestamp: TIMESTAMP, params: params) { (parentMessage, threadedReplies, error) in
    if error != nil {
        // Handle error.
    }

    // A list of replies of the specified parent message timestamp is successfully retrieved.
    // Through the "threadedReplies" parameter of the callback method,
    // you can access and display the data of each message from the result list that Sendbird server has passed to the callback method.
    ...
}

List of arguments

ArgumentTypeDescription

TIMESTAMP

long long

Specifies the timestamp to be the reference point of the retrieval, in Unix milliseconds format.


View a single message

You can retrieve a specific message by creating and passing the SBDMessageRetrievalParams object as a parameter to the getMessageWithParams:completionHandler: method.

Objective-C
Swift
Light Color Skin
Copy
SBDMessageRetrievalParams *params = [[SBDMessageRetrievalParams alloc] init];
params.messageId = MESSAGE_ID;
params.channelType = CHANNEL_TYPE;
params.channelUrl = CHANNEL_URL;
Light Color Skin
Copy
let params = SBDMessageRetrievalParams()
params.messageId = MESSAGE_ID
params.channelType = CHANNEL_TYPE
params.channelUrl = CHANNEL_URL

SBDMessageRetrievalParams

PropertyDescription

messageID

Type: long long

Specifies the unique ID of the message to retrieve.

channelType

Type: SBDChannelType

Specifies the type of the channel.

channelURL

Type: NSString

Specifies the URL of the channel to retrieve the message.

Objective-C
Swift
Light Color Skin
Copy
[SBDBaseMessage getMessageWithParams:params completionHandler:^(SBDBaseMessage * _Nullable message, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The specified message is successfully retrieved.
    ...
}];
Light Color Skin
Copy
SBDBaseMessage.getWith(params) { (message, error) in
    if error != nil {
        // Handle error.
    }

    // The specified message is successfully retrieved.
    ...
}

Reply to a message

You can reply to a specific message in a channel through the sendUserMessageWithParams:completionHandler: or sendFileMessageWithParams:completionHandler: method. To do so, you should create a SBDUserMessageParams or a SBDFileMessageParams object and then specify the parentMessageId property of the object. Sending reply messages works the same way as sending regular messages to a channel except replies have an additional parentMessageId property.

Reply with a text message

When replying to a message through the sendUserMessageWithParams:completionHandler: method, you should specify and pass a SBDUserMessageParams object to the method as a parameter.

Objective-C
Swift
Light Color Skin
Copy
SBDUserMessageParams *params = [[SBDUserMessageParams alloc] initWithMessage:MESSAGE_TEXT];
params.parentMessageId = PARENT_MESSAGE_ID;
Light Color Skin
Copy
let params = SBDUserMessageParams(message: MESSAGE_TEXT)
params?.parentMessageId = PARENT_MESSAGE_ID

SBDUserMessageParams

PropertyTypeDescription

parentMessageId

long long

Specifies the unique ID of a parent message which has a thread of replies. If the message sent through the sendUserMessageWithParams:completionHandler: method is a parent message, the value of this property is 0. If the message is a reply to a parent message, the value is the message ID of the parent message.

Objective-C
Swift
Light Color Skin
Copy
[channel sendUserMessageWithParams:params completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A reply to a specific message in the form of a text message is successfully sent.
    ...
}];
Light Color Skin
Copy
channel?.sendUserMessage(with: params!, completionHandler: { (message, error) in
    if error != nil {
        // Handle error.
    }

    // A reply to a specific message in the form of a text message is successfully sent.
    ...
})

Reply with a file message

When replying with a file message through the sendFileMessageWithParams:completionHandler: method, you should specify and pass a SBDFileMessageParams object to the method as a parameter.

Objective-C
Swift
Light Color Skin
Copy
SBDFileMessageParams *params = [[SBDFileMessageParams alloc] initWithFile:file];
params.parentMessageId = PARENT_MESSAGE_ID;
Light Color Skin
Copy
let params = SBDFileMessageParams(file: FILE!)
params?.parentMessageId = PARENT_MESSAGE_ID

SBDFileMessageParams

PropertyTypeDescription

parentMessageId

long long

Specifies the unique ID of a parent message which has a thread of replies. If the message sent through the sendFileMessageWithParams:completionHandler: method is a parent message, the value of this property is 0. If the message is a reply to a parent message, the value is the message ID of the parent message.

Objective-C
Swift
Light Color Skin
Copy
[channel sendFileMessageWithParams:params completionHandler:^(SBDFileMessage * _Nullable fileMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A reply to a specific message in the form of a file message is successfully sent.
    ...
}];
Light Color Skin
Copy
channel?.sendFileMessage(with: params!, completionHandler: { (message, error) in
    if error != nil {
        // Handle error.
    }

    // A reply to a specific message in the form of a file message is successfully sent.
    ...
})

List changelogs

You can retrieve message changelogs.

Load message changelogs

Each message changelog has distinct properties such as a timestamp that indicates when a message was updated and a unique ID of a deleted message. Based on these two properties, you can retrieve message changelogs in two different ways: either by timestamp or by token. Both getMessageChangeLogsSinceToken:params:completionHandler: and getMessageChangeLogsSinceTimestamp:params:completionHandler: methods require a parameter SBDMessageChangeLogsParams object to determine what messages to return.

Objective-C
Swift
Light Color Skin
Copy
SBDMessageChangeLogsParams *params = [[SBDMessageChangeLogsParams alloc] init];
params.includeReplies = INCLUDE_REPLIES;
params.includeThreadInfo = INCLUDE_THREAD_INFO;
params.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT;
Light Color Skin
Copy
let params = SBDMessageChangeLogsParams()
params.includeReplies = INCLUDE_REPLIES
params.includeThreadInfo = INCLUDE_THREAD_INFO
params.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT

SBDMessageChangeLogsParams

The following table lists the properties of this class.

Property nameTypeDescription

includeReplies

bool

Determines whether replies are included in the results.

includeThreadInfo

bool

Determines whether to include the thread information of the messages in the results when the results contain parent messages.

includeParentMessageText

bool

Determines whether to include the parent message text in the results when the messages are replies in a thread. If the type of the parent message is SBDUserMessage, the value is a message property. If it is SBDFileMessage, the value is the name of the uploaded file.

By timestamp

You can retrieve message changelogs by specifying a timestamp. The results will include changelogs that were created after the specified timestamp.

Objective-C
Swift
Light Color Skin
Copy
[channel getMessageChangeLogsSinceTimestamp:TIMESTAMP params:params completionHandler:^(NSArray * _Nullable updatedMessages, NSArray * _Nullable deletedMessageIds, BOOL hasMore, NSString * _Nullable token, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A list of message changelogs created after the specified timestamp is successfully retrieved.
    ...
];
Light Color Skin
Copy
channel?.getMessageChangeLogs(sinceTimestamp: TIMESTAMP, params: params, completionHandler: { (updatedMessages, deletedMessageIds, hasMore, token, error) in
    if error != nil {
        // Handle error.
    }

    // A list of message changelogs created after the specified timestamp is successfully retrieved.
    ...
})

List of arguments

ArgumentTypeDescription

TIMESTAMP

long long

Specifies the timestamp to be the reference point for changelogs to retrieve, in Unix milliseconds format.

By token

You can also retrieve message changelogs by specifying a token. The token is an opaque string that marks the starting point of the next page in the result set and it is included in the callback of the previous call. Based on the token, the next page will start with changelogs that were created after the specified token.

Objective-C
Swift
Light Color Skin
Copy
[channel getMessageChangeLogsSinceToken:TOKEN params:params completionHandler:^(NSArray * _Nullable updatedMessages, NSArray * _Nullable deletedMessageIds, BOOL hasMore, NSString * _Nullable token, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A list of message changelogs created after the specified token is successfully retrieved.
    ...
}];
Light Color Skin
Copy
channel?.getMessageChangeLogs(sinceToken: TOKEN, params: params, completionHandler: { (updatedMessages, deletedMessageIds, hasMore, token, error) in
    if error != nil {
        // Handle error.
    }

    // A list of message changelogs created after the specified token is successfully retrieved.
    ...
})

Event delegate

Once a reply is created or deleted from a thread, the channel:didUpdateThreadInfo: event delegate method is invoked. The method returns a SBDThreadInfoUpdateEvent object that has the latest information about the thread. This object needs to be applied to the parent message object.

Note: Like other messages, when a reply is created in a channel, the onMessageReceived() method of the channel event handler in client apps will be called.

Objective-C
Swift
Light Color Skin
Copy
- (void)channel:(nonnull SBDBaseChannel *)channel didUpdateThreadInfo:(nonnull SBDThreadInfoUpdateEvent *)threadInfoUpdateEvent {
    // Look for a message that has threadInfoUpdateEvent.targetMessageId
    // Apply the event to the message.
    [message applyThreadInfoUpdateEvent:threadInfoUpdateEvent];
}
Light Color Skin
Copy
func channel(_ channel: SBDBaseChannel, didUpdateThreadInfo threadInfoUpdateEvent: SBDThreadInfoUpdateEvent) {
    // Look for a message that has threadInfoUpdateEvent.targetMessageId
    // Apply the event to the message.
    message.apply(threadInfoUpdateEvent)
}

List of parameters

Parameter nameDescription

channel

Type: SBDBaseChannel

Specifies the channel that has the message thread.

threadInfoUpdateEvent

Type: SBDThreadInfoUpdateEvent

Specifies a SBDThreadInfoUpdateEvent object that has the latest information about the thread.