Home
/
Chat
/
iOS

Open channel

An open channel is a Twitch-style public chat where users can easily join without permission. Sendbird Chat SDK now supports two operation systems for open channels, which are classic and dynamic partitioning. These two systems offer the same features and functions, except that dynamic partitioning allows open channels to accommodate a massive number of users.

Open channels can be used in short-lived live events, such as streaming, news-feed type messaging to massive audience, or events that don't require a permanent membership.

Note: To learn about differences between open channels and group channels, see Channel types.


Classic vs. Dynamic partitioning

Classic open channels are the original open channels Sendbird has been providing, and a single classic open channel can handle up to 1,000 participants.

Note: Sendbird applications created before December 15, 2020, are using classic open channels.

On the other hand, dynamic partitioning open channels are designed to accommodate an even larger number of users using a set number of subchannels, starting from 2,000 to 60,000 participants. This new system, called dynamic partitioning, enables flexible scaling of open channels by creating or merging subchannels within the open channels and evenly allocating participants among the subchannels while providing a seamless and well-paced chat experience to all users.

Note: The classic open channels will be deprecated by the end of March 2021 but the classic channels created before the deprecation will remain and function the same way. Meanwhile, all Chat SDK users will be automatically migrated to the new dynamic partitioning system when the deprecation takes place. If you wish to convert to dynamic partitioning open channels beforehand, contact our support team.

Learn more about how dynamic partitioning open channel operates in the Open channel guide of Platform API.


Create a channel

An open channel is ideal for use cases that require a small and static number of channels. To create an open channel from the Sendbird Dashboard, do the following:

  1. In your dashboard, go to the Chat > Open channels, and then click Create channel at the top-right corner.
  2. In the dialog box that appears, specify the name, unique URL, cover image, and custom type of a channel.

You can also create a channel on demand or dynamically through the Chat SDK or the Chat API.

Objective-C
Swift
Light Color Skin
Copy
[SBDOpenChannel createChannelWithName:NAME coverUrl:COVER_URL data:DATA operatorUsers:OPERATOR_USERS completionHandler:^(SBDOpenChannel * _Nullable openChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // An open channel is successfully created.
    // Through the "openChannel" parameter of the callback method,
    // you can get the open channel's data from the result object that Sendbird server has passed to the callback method.
    NSString *channelUrl = openChannel.channelUrl;
    ...
}];
Light Color Skin
Copy
SBDOpenChannel.createChannel(withName: NAME, coverUrl: COVER_URL, data: DATA, operatorUsers: OPERATOR_USERS, completionHandler: { (openChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    // An open channel is successfully created.
    // Through the "openChannel" parameter of the callback method,
    // you can get the open channel's data from the result object that Sendbird server has passed to the callback method.
    let channelUrl = openChannel?.channelUrl
    ...
})

Otherwise, you can create an open channel by configuring a SBDOpenChannelParams object like the following.

Objective-C
Swift
Light Color Skin
Copy
NSMutableArray *ops = [[NSMutableArray alloc] init];
[ops addObject:@"Jeff"];

SBDOpenChannelParams *params = [[SBDOpenChannelParams alloc] init];
[params setOperatorUserIds:ops];    // Or setOperators:
[params setName:@"NAME"];
[params setChannelUrl:@"UNIQUE_CHANNEL_URL"];   // In an open channel, you can create a new channel by specifying its unique channel URL.
[params setCoverImage:FILE];        // Or setCoverUrl:
[params setData:@"DATA"];
[params setCustomType:@"CUSTOM_TYPE"];

[SBDOpenChannel createChannelWithParams:params completionHandler:^(SBDOpenChannel * _Nullable openChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // An open channel with detailed configuration is successfully created.
    // By using openChannel.channelUrl, openChannel.data, openChannel.customType, and so on,
    // you can access the result object from Sendbird server to check your SBDOpenChannelParams configuration.
    NSString *channelUrl = openChannel.channelUrl;
    ...
}];
Light Color Skin
Copy
var ops: [String] = []
ops.append("Jeff")

var params = SBDOpenChannelParams()
params.operatorUserIds = ops        // Or .operators
params.name = NAME
params.channelUrl = UNIQUE_CHANNEL_URL    // In an open channel, you can create a new channel by specifying its unique channel URL.
params.coverImage = FILE            // Or .coverUrl
params.data = DATA
params.customType = CUSTOM_TYPE

SBDOpenChannel.createChannel(with: params, completionHandler: { (openChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    // An open channel with detailed configuration is successfully created.
    // By using openChannel.channelUrl, openChannel.data, openChannel.customType, and so on,
    // you can access the result object from Sendbird server to check your SBDOpenChannelParams configuration.
    let channelUrl = openChannel?.channelUrl
    ...
})

When creating a channel, you can also append additional information like cover image and description by passing several arguments to the corresponding parameters.

Objective-C
Swift
Light Color Skin
Copy
[SBDOpenChannel createChannelWithName:NAME coverImage:COVER_IMAGE coverImageName:@"" data:DATA operatorUsers:OPERATOR_USERS customType:CUSTOM_TYPE progressHandler:nil completionHandler:^(SBDOpenChannel * _Nullable openChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // An open channel with detailed configuration is successfully created.
    NSString *channelUrl = openChannel.channelUrl;
    ...
}];
Light Color Skin
Copy
SBDOpenChannel.createChannel(withName: NAME, coverImage: COVER_IMAGE, coverImageName: "", data: DATA, operatorUsers: OPERATOR_USERS, customType: CUSTOM_TYPE, progressHandler: nil) { (openChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    // An open channel with detailed configuration is successfully created.
    let channelUrl = openChannel?.channelUrl
    ...
}

List of arguments

ArgumentDescription

NAME

Type: NSString
Specifies the channel topic, or the name of the channel.

COVER_IMAGE

Type: NSData
Uploads a file for the cover image of the channel.

DATA

Type: NSString
Specifies additional channel information such as a long description of the channel or JSON formatted string.

OPERATOR_USERS

Type: NSArray
Specifies an array of one or more users to register as operators of the channel. Operators can delete any messages, and also view all messages in the channel without any filtering or throttling.

CUSTOM_TYPE

Type: NSString
Specifies the custom channel type which is used for channel grouping.

Note: See the Advanced section for more information on cover images and custom types.


Enter a channel

A user must enter an open channel to receive messages. The user can enter up to 10 open channels at once, but the connection is only valid within the current session. When a user who is disconnected from Sendbird server with the disconnectWithCompletionHandler: reconnects to the server with connectWithUserId:, you should make sure the user re-enters the channels in order to continue receiving messages.

When a user who is already a participant in an open channel moves the app to the background, the user will be disconnected from Sendbird server. But when the user's app returns to the foreground, the Chat SDK will automatically re-enter the user to the participating channel.

Note: When a user is reconnected by attempts of the SBDMain instance from a temporary unstable connection, the Chat SDK will automatically re-enter the user to the participating channel.

Objective-C
Swift
Light Color Skin
Copy
[SBDOpenChannel getChannelWithUrl:CHANNEL_URL completionHandler:^(SBDOpenChannel * _Nullable openChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // Call the instance method of the result object in the "openChannel" parameter of the callback method.
    [openChannel enterChannelWithCompletionHandler:^(SBDError * _Nullable error) {
        if (error != nil) {
            // Handle error.
        }

        // The current user successfully enters the open channel,
        // and can chat with other users in the channel by using APIs.
        ...
    }];
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL, completionHandler: { (openChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    // Call the instance method of the result object in the "openChannel" parameter of the callback method.
    openChannel?.enter(completionHandler: { (error) in
        guard error == nil else {
            // Handle error.
        }

        // The current user successfully enters the open channel,
        // and can chat with other users in the channel by using APIs.
        ...
    })
})

Exit a channel

If a user exits an open channel, the user can't receive any messages from that channel.

Objective-C
Swift
Light Color Skin
Copy
[SBDOpenChannel getChannelWithUrl:CHANNEL_URL completionHandler:^(SBDOpenChannel * _Nullable openChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // Call the instance method of the result object in the "openChannel" parameter of the callback method.
    [openChannel exitChannelWithCompletionHandler:^(SBDError * _Nullable error) {
        if (error != nil) {
            // Handle error.
        }

        // The current user successfully exits the open channel.
        ...
    }];
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL, completionHandler: { (openChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    // Call the instance method of the result object in the "openChannel" parameter of the callback method.
    openChannel?.exitChannel(completionHandler: { (error) in
        guard error == nil else {
            // Handle error.
        }

        // The current user successfully exits the open channel.
        ...
    })
})

Freeze and unfreeze a channel

An open channel can be freezed only with the Sendbird Dashboard or Chat API as opposed to a group channel which operators of the channel can do that via the Chat SDK.

To freeze a channel, go to Chat > Open channels on the dashboard, select an open channel, and click the Freeze icon at the upper right corner. To unfreeze, select the frozen channel and click the Freeze icon again.

Note : In a frozen channel, participants can't chat with each other but the operators can send a message to the channel.


Delete a channel

Only the operators of an open channel can delete the channel. Otherwise, an error is returned through the completionHandler.

Note: The following code works properly in the operators' client apps only.

Objective-C
Swift
Light Color Skin
Copy
[openChannel deleteChannelWithCompletionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The channel is successfully deleted.
    ...
}];
Light Color Skin
Copy
openChannel.deleteChannel(completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    // The channel is successfully deleted.
    ...
})

Retrieve a list of channels

You can retrieve a list of open channels by using the SBDOpenChannelListQuery's loadNextPageWithCompletionHandler: method which returns a list of SBDOpenChannel objects.

Objective-C
Swift
Light Color Skin
Copy
SBDOpenChannelListQuery *listQuery = [SBDOpenChannel createOpenChannelListQuery];

[listQuery loadNextPageWithCompletionHandler:^(NSArray * _Nullable openChannels, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A list of open channels is successfully retrieved.
    // Through the "openChannels" parameter of the callback method,
    // you can access the data of each open channel from the result list that Sendbird server has passed to the callback method.
    [self.channels addObjectsFromArray:openChannels];
    ...
}];
Light Color Skin
Copy
let listQuery = SBDOpenChannel.createOpenChannelListQuery()!

listQuery.loadNextPage(completionHandler: { (openChannels, error) in
    guard error == nil else {
        // Handle error.
    }

    // A list of open channels is successfully retrieved.
    // Through the "openChannels" parameter of the callback method,
    // you can access the data of each open channel from the result list that Sendbird server has passed to the callback method.
    self.channels += openChannels!
    ...
})

Retrieve a channel by URL

Since a channel URL is a unique identifier of an open channel, you can use a URL when retrieving a channel object.

Objective-C
Swift
Light Color Skin
Copy
[SBDOpenChannel getChannelWithUrl:CHANNEL_URL completionHandler:^(SBDOpenChannel * _Nonnull openChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // Through the "openChannel" parameter of the callback method,
    // the open channel object identified with the CHANNEL_URL is returned by Sendbird server,
    // and you can get the open channel's data from the result object.
    NSString *channelName = openChannel.name;
    ...
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL, completionHandler: { (openChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    // Through the "openChannel" parameter of the callback method,
    // the open channel object identified with the CHANNEL_URL is returned by Sendbird server,
    // and you can get the open channel's data from the result object.
    let channelName = openChannel?.name
    ...
})

Note: We recommend that you store a user's channel URLs to handle the lifecycle or state changes of your app, or any other unexpected situations. For example, when a user is disconnected from Sendbird server due to switching to another app temporarily, you can provide a smooth restoration of the user's state using a stored URL to fetch the appropriate channel instance.


Send a message

To an entered open channel, a user can send messages of the following types:

Message typeDescription

UserMessage

A text message sent by a user

FileMessage

A binary file message sent by a user

In addition to these message types, you can further subclassify a message by specifying its custom type. This custom type takes on the form of a NSString and can be used to search or filter messages. It allows you to append information to your message and customize message categorization.

The following code shows several types of parameters that you can configure to customize text messages by using SBDUserMessageParams. Under the SBDUserMessageParams object, you can assign values to message, data and other properties. By assigning arbitrary string to the data property, you can set custom font size, font type or JSON object. To send your messages, you need to pass the SBDUserMessageParams object as an argument to the parameter in the sendUserMessageWithParams:completionHandler: method.

Through the completionHandler of the sendUserMessageWithParams:completionHandler: method, Sendbird server always notifies whether your message has been successfully sent to the channel. When there is a delivery failure due to network issues, an exception is returned through the callback method.

Objective-C
Swift
Light Color Skin
Copy
SBDUserMessageParams *params = [[SBDUserMessageParams alloc] init];
[params setMessage:MESSAGE];
[params setCustomType:CUSTOM_TYPE];
[params setData:DATA];
[params setMentionType:SBDMentionTypeUsers];        // Either SBDMentionTypeUsers or SBDMentionTypeChannel
[params setMentionedUserIds:@[@"Jeff", @"Julia"]];  // Or setMentionedUsers:LIST_OF_USERS_TO_MENTION
[params setMetaArrays:@{@"itemType": @[@"tablet"], @"quality": @[@"best", @"good"]}];   // A key-value pair
[params setTargetLanguages:@[@"fr", @"de"]];        // French and German
[params setPushNotificationDeliveryOption:SBDPushNotificationDeliveryOptionDefault];

[openChannel sendUserMessageWithParams:params completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A text message with detailed configuration is successfully sent to the channel.
    // By using userMessage.messageId, userMessage.message, userMessage.customType, and so on,
    // you can access the result object from Sendbird server to check your SBDUserMessageParams configuration.
    // The current user can receive messages from other users through the channel:didReceiveMessage: method of an event delegate.
    long long messageId = userMessage.messageId;
    ...
}];
Light Color Skin
Copy
var params = SBDUserMessageParams()
params.message = MESSAGE
params.customType = CUSTOM_TYPE
params.data = DATA
params.mentionType = SBDMentionTypeUsers        // Either SBDMentionTypeUsers or SBDMentionTypeChannel
params.mentionedUserIds = ["Jeff", "Julia"]     // Or .mentionedUsers = LIST_OF_USERS_TO_MENTION
params.metaArrays = ["itemType": ["tablet"], "quality": ["best", "good"]]   // A key-value pair
params.targetLanguages = ["fr", "de"]           // French and German
params.pushNotificationDeliveryOption = .default

openChannel.sendUserMessage(with: params, completionHandler: { (userMessage, error) in
    guard error == nil else {
        // Handle error.
    }

    // A text message with detailed configuration is successfully sent to the channel.
    // By using userMessage.messageId, userMessage.message, userMessage.customType, and so on,
    // you can access the result object from Sendbird server to check your SBDUserMessageParams configuration.
    // The current user can receive messages from other users through the didReceiveMessage() method of an event delegate.
    let messageId = userMessage?.messageId;
    ...
})

A user can also send binary files through the Chat SDK. The two ways to send a binary file are: sending the file itself, or sending a URL.

Sending a raw file means you're uploading it to Sendbird server where it can be downloaded in client apps. When you upload a file directly to the server, there is a size limit imposed on the file depending on your plan. You can see the limit in your dashboard and adjust it with our sales team.

The other option is to send a file hosted on your server. You can pass the file's URL, which represents its location, as an argument to a parameter. In this case, your file is not hosted on Sendbird server and it can only be downloaded from your own server. When you send a file message with a URL, there is no limit on the file size since it's not directly uploaded to Sendbird server.

Note: You can use sendFileMessagesWithParams:progressHandler:sentMessageHandler:completionHandler:, which is another method that allows you to send up to 20 file messages per one method call. Refer to our API Reference to learn more about it.

The following code shows several types of parameters that you can configure to customize your file messages by using SBDFileMessageParams. Under the SBDFileMessageParams object, you can assign specific values to customType and other properties. To send your messages, you need to pass the SBDFileMessageParams object as an argument to the parameter in the sendFileMessageWithParams:completionHandler: method.

Through the completionHandler of the sendFileMessageWithParams:completionHandler: method, Sendbird server always notifies whether your message has been successfully sent to the channel. When there is a delivery failure due to network issues, an exception is returned through the callback method.

Objective-C
Swift
Light Color Skin
Copy
// Sending a file message with a raw file
NSMutableArray *thumbnailSizes = [[NSMutableArray alloc] init];

[thumbnailSizes addObject:[SBDThumbnailSize makeWithMaxCGSize:CGSizeMake(100.0, 100.0)]];   // Allowed number of thumbnail images: 3
[thumbnailSizes addObject:[SBDThumbnailSize makeWithMaxWidth:200.0 maxHeight:200.0]];

SBDFileMessageParams *params = [[SBDFileMessageParams alloc] init];
[params setFile:FILE];                  // or setFileUrl:FILE_URL (You can also send a file message with a file URL.)
[params setFileName:FILE_NAME];
[params setFileSize:FILE_SIZE];
[params setMimeType:MIME_TYPE];
[params setThumbnailSizes:thumbnailSizes];
[params setCustomType:CUSTOM_TYPE];
[params setMentionType:SBDMentionTypeUsers];        // Either SBDMentionTypeUsers or SBDMentionTypeChannel
[params setMentionedUserIds:@[@"Jeff", @"Julia"]];  // Or setMentionedUsers:LIST_OF_USERS_TO_MENTION
[params setPushNotificationDeliveryOption:SBDPushNotificationDeliveryOptionDefault];

[openChannel sendFileMessageWithParams:params completionHandler:^(SBDFileMessage * _Nonnull fileMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A file message with detailed configuration is successfully sent to the channel.
    // By using fileMessage.messageId, fileMessage.fileName, fileMessage.customType, and so on,
    // you can access the result object from Sendbird server to check your SBDFileMessageParams configuration.
    // The current user can receive messages from other users through the channel:didReceiveMessage: method of an event delegate.
    long long messageId = fileMessage.messageId;
    ...
}];
Light Color Skin
Copy
// Sending a file message with a raw file
var thumbnailSizes = [SBDThumbnailSize]()

thumbnailSizes.append(SBDThumbnailSize.make(withMaxCGSize: CGSize(width: 100.0, height: 100.0))!)   // Allowed number of thumbnail images: 3
thumbnailSizes.append(SBDThumbnailSize.make(withMaxWidth: 200.0, maxHeight: 200.0)!)

var params = SBDFileMessageParams()
params.file = FILE                  // Or .fileUrl = FILE_URL (You can also send a file message with a file URL.)
params.fileName = FILE_NAME
params.fileSize = FILE_SIZE
params.mimeType = MIME_TYPE
params.thumbnailSizes = thumbnailSizes
params.customType = CUSTOM_TYPE
params.mentionType = SBDMentionTypeUsers        // Either SBDMentionTypeUsers or SBDMentionTypeChannel
params.mentionedUserIds = ["Jeff", "Julia"]     // Or .mentionedUsers = LIST_OF_USERS_TO_MENTION
params.pushNotificationDeliveryOption = SBDPushNotificationDeliveryOptionDefault

openChannel.sendFileMessage(with: params, completionHandler: { (fileMessage, error) in
    guard error == nil else {
        // Handle error.
    }

    // A file message with detailed configuration is successfully sent to the channel.
    // By using fileMessage.messageId, fileMessage.fileName, fileMessage.customType, and so on,
    // you can access the result object from Sendbird server to check your SBDFileMessageParams configuration.
    // The current user can receive messages from other users through the didReceiveMessage() method of an event delegate.
    let messageId = fileMessage?.messageId
    ...
})

If your app goes to the background while uploading a file such as a profile image or picture, the app can complete the uploading process using the application:handleEventsForBackgroundURLSession:completionHandler: method in your AppDelegate. To complete a file upload in progress on the background, a background event delegate should be added and implemented in the AppDelegate. If you don't want to upload a file on the background mode, remove the following delegation in the AppDelegate.

Objective-C
Swift
Light Color Skin
Copy
// AppDelegate.m
@implementation AppDelegate

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler {
    if (completionHandler != nil) {
        completionHandler();
    }
}

@end
Light Color Skin
Copy
// AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        debugPrint("method for handling events for background URL session is waiting to be process. background session id: \(identifier)")
        completionHandler()
    }
}

Send a critical alert message to iOS devices

A critical alert is a notification that can be sent to iOS devices even when mute or Do Not Disturb is turned on. Critical alert messages can be sent to iOS devices through the sendUserMessageWithParams:completionHandler: and sendFileMessageWithParams:completionHandler: methods. To do so, create an SBDAppleCriticalAlertOptions instance and set it as an attribute of a SBDUserMessageParams instance. Then pass the created SBDUserMessageParams instance as an argument to a parameter in the sendUserMessageWithParams:completionHandler: or sendFileMessageWithParams:completionHandler: method.

Note: To learn more about how to set critical alerts, visit Apple critical alerts.

Objective-C
Swift
Light Color Skin
Copy
// Send a critical alert user message.
SBDUserMessageParams *userMessageParams = [[SBDUserMessageParams alloc] initWithMessage:MESSAGE_TEXT];
SBDAppleCriticalAlertOptions *options = [[SBDAppleCriticalAlertOptions alloc] init];
options.name = @"name";
options.volume = 0.7;   // Acceptable values for `options.volume` range from 0 to 1.0, inclusive.
userMessageParams.appleCriticalAlertOptions = options;
[openChannel sendUserMessageWithParams:userMessageParams completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }
}];

// Send a critical alert file message.
SBDFileMessageParams *fileMessageParams = [[SBDFileMessageParams alloc] initWithFile:FILE];
SBDAppleCriticalAlertOptions *options = [[SBDAppleCriticalAlertOptions alloc] init];
options.name = @"name";
options.volume = 0.7;   // Acceptable values for `options.volume` range from 0 to 1.0, inclusive.
fileMessageParams.appleCriticalAlertOptions = options;
[openChannel sendFileMessageWithParams:fileMessageParams completionHandler:^(SBDFileMessage * _Nullable fileMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }
}];
Light Color Skin
Copy
// Send a critical alert user message.
let userMessageParams = SBDUserMessageParams(message: MESSAGE_TEXT)!
let options = SBDAppleCriticalAlertOptions()
options.name = "name"
options.volume = 0.7    // Acceptable values for `options.volume` range from 0 to 1.0, inclusive.
userMessageParams.appleCriticalAlertOptions = options
openChannel.sendUserMessage(with: userMessageParams) { (userMessage, error) in
    if error != nil {
        // Handle error.
    }
}
// Send a critical alert file message.
let fileMessageParams = SBDFileMessageParams(file: FILE!)
let options = SBDAppleCriticalAlertOptions()
options.name = "name"
options.volume = 0.7    // Acceptable values for `options.volume` range from 0 to 1.0, inclusive.
fileMessageParams!.appleCriticalAlertOptions = options
openChannel.sendFileMessage(with: fileMessageParams!) { (fileMessage, error) in
    if error != nil {
        // Handle error.
    }
}

Receive messages through a channel delegate

The current user can receive messages sent by other participants through the channel:didReceiveMessage: method in the channel delegate. A SBDBaseMessage object for each received message is one of the following message types.

Message typeDescription

UserMessage

A text message sent by a user

FileMessage

A binary file message sent by a user

AdminMessage

A text message sent by an admin through the Chat API

The UNIQUE_DELEGATE_ID is a unique identifier to register multiple concurrent delegates.

Objective-C
Swift
Light Color Skin
Copy
@interface OpenChannelViewController : UIViewController

@end

@implementation OpenChannelChattingViewController

- (void)initOpenChannelChattingViewController {
    [SBDMain addChannelDelegate:self identifier:UNIQUE_DELEGATE_ID];
}


- (void)channel:(SBDBaseChannel * _Nonnull)sender didReceiveMessage:(SBDBaseMessage * _Nonnull)message {
    // You can customize how to display the different types of messages with the result object in the "message" parameter.
    if (message isKindOfClass:[SBDUserMessage class]]) {
        ...
    }
    else if (message isKindOfClass:[SBDFileMessage class]]) {
        ...
    }
    else if (message isKindOfClass:[SBDAdminMessage class]]) {
        ...
    }
}

@end
Light Color Skin
Copy
class OpenChannelChattingViewController: UIViewController, SBDChannelDelegate {
    SBDMain.add(self, identifier: self.delegateIdentifier)

    func channel(_ sender: SBDBaseChannel, didReceive message: SBDBaseMessage) {
        // You can customize how to display the different types of messages with the result object in the "message" parameter.
        if message is SBDUserMessage {
            ...
        }
        else if message is SBDFileMessage {
            ...
        }
        else if message is SBDAdminMessage {
            ...
        }
    }
}

If the UI isn't valid anymore, remove the channel delegate.

Objective-C
Swift
Light Color Skin
Copy
[SBDMain removeChannelDelegateForIdentifier:UNIQUE_DELEGATE_ID];
Light Color Skin
Copy
SBDMain.removeChannelDelegate(forIdentifier: UNIQUE_DELEGATE_ID)

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
// Create a `SBDUserMessageParams` object.
SBDUserMessageParams *params = [[SBDUserMessageParams alloc] initWithMessage:MESSAGE_TEXT];
params.parentMessageId = PARENT_MESSAGE_ID;
...

// Pass the params to the parameter in the `sendUserMessageWithParams:completionHandler:` method.
[openChannel 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
// Create a `SBDUserMessageParams` object.
let params = SBDUserMessageParams(message: MESSAGE_TEXT)
params?.parentMessageId = PARENT_MESSAGE_ID
...

// Pass the params to the parameter in the `sendUserMessageWithParams:completionHandler:` method.
openChannel?.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.
    ...
})

List of arguments

ArgumentDescription

PARENT_MESSAGE_ID

Type: 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.

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
// Create a `SBDFileMessageParams` object.
SBDFileMessageParams *params = [[SBDFileMessageParams alloc] initWithFile:file];
params.parentMessageId = PARENT_MESSAGE_ID; // This 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.
...

// Pass the params to the parameter in the `sendFileMessageWithParams:completionHandler:` method.
[openChannel 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
// Create a `SBDFileMessageParams` object.
let params = SBDFileMessageParams(file: FILE!)
params?.parentMessageId = PARENT_MESSAGE_ID // This 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.
...

// Pass the params to the parameter in the `sendFileMessageWithParams:completionHandler:` method.
openChannel?.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 of arguments

ArgumentDescription

PARENT_MESSAGE_ID

Type: 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.


Mention other participants in a message

When a participant wants to call the attention of other participants in an open channel where push notifications are not allowed by default, they can mention those participants in a message. To do so, you should:

  1. Specify a list of the user IDs to mention.
  2. Add the list to either SBDUserMessageParams or FileMessageParams which may contain options for further action.
  3. Pass the params to either sendUserMessageWithParams:...: or sendFileMessageWithParams:...:.
  4. Then only up to 10 participants mentioned in the message will be notified.
Objective-C
Swift
Light Color Skin
Copy
NSMutableArray *userIDsToMention = [[NSMutableArray alloc] init];
[userIDsToMention addObject:@"Harry"];
[userIDsToMention addObject:@"Jay"];
[userIDsToMention addObject:@"Jin"];

SBDUserMessageParams *params = [[SBDUserMessageParams alloc] initWithMessage:MESSAGE];
...
[params setMentionedUserIds:userIDsToMention];

[openChannel sendUserMessageWithParams:params completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
var userIDsToMention: [String] = []
userIDsToMention.append("Harry")
userIDsToMention.append("Jay")
userIDsToMention.append("Jin")

let params = SBDUserMessageParams(message: MESSAGE)
...
params?.mentionedUserIds = userIDsToMention

guard let paramsBinded: SBDUserMessageParams = params else {
    return
}

openChannel.sendUserMessage(with: paramsBinded, completionHandler: { (userMessage, error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

Load previous messages

By using the loadPreviousMessagesWithLimit:reverse:completionHandler: method of a SBDPreviousMessageListQuery instance which returns a list of SBDBaseMessage objects, you can retrieve a set number of previous messages in an open channel. With a returned list, you can display the past messages in your UI once they have loaded.

Objective-C
Swift
Light Color Skin
Copy
// There should only be one single instance per channel view.
SBDPreviousMessageListQuery *listQuery = [openChannel createPreviousMessageListQuery];
listQuery.customTypeFilter = @"greeting";
...

// Retrieving previous messages.
[listQuery loadPreviousMessagesWithLimit:LIMIT reverse:REVERSE completionHandler:^(NSArray * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
// There should be only one single instance per channel.
let listQuery = openChannel.createPreviousMessageListQuery()
listQuery?.customTypeFilter = "greeting"
...

// Retrieving previous messages
listQuery?.loadPreviousMessages(withLimit: LIMIT, reverse: REVERSE, completionHandler: { (messages, error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

List of arguments

ArgumentDescription

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 set to YES, returns a list of messages which the latest comes at first and the earliest at last. the results are sorted in reverse order. If set to NO, returns a list of messages which the earliest comes at first and the latest at last.

A limit parameter determines how many messages to be included in a returned list. A SBDPreviousMessageListQuery instance itself does pagination of a result set according to the value of the limit parameter, and internally manages a token to retrieve the next page in the result set.

Each time the loadPreviousMessagesWithLimit:reverse:completionHandler: method is called, the instance retrieves a set number of messages in the next page and then updates the token's value to complete the current call and prepare a next call.

If you create a new query instance and call the loadPreviousMessagesWithLimit:reverse:completionHandler: method, a set number of the most recent messages are retrieved because its token has nothing to do with the previously created instance. So we recommend that you create a single query instance and store it as a member variable for traversing through the entire message history.

Note: Before calling the loadPreviousMessagesWithLimit:reverse:completionHandler: method again, you should receive a success callback through the completionHandler first.


Load messages by timestamp or message ID

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

Note: The getPreviousMessages() method is deprecated as of August 2021. Accordingly, use the getMessagesByTimestamp:params:completionHandler: method instead.

The following code shows several types of parameters that you can configure to customize a message query by using SBDMessageListParams. Under the SBDMessageListParams object, you can assign specific values to previousResultSize, messageType, and other properties. To retrieve messages in a channel, you need to pass the SBDMessageListParams object as an argument to the parameter in the getMessagesByTimestamp:params:completionHandler: method.

Objective-C
Swift
Light Color Skin
Copy
SBDMessageListParams *params = [[SBDMessageListParams alloc] init];
[params setIsInclusive:IS_INCLUSIVE];
[params setPreviousResultSize:PREVIOUS_RESULT_SIZE];
[params setNextResultSize:NEXT_RESULT_SIZE];
[params setReverse:REVERSE];
[params setMessageType:MESSAGE_TYPE];
[params setCustomType:CUSTOM_TYPE];
...

[openChannel 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
var params = SBDMessageListParams()
params.isInclusive = IS_INCLUSIVE
params.previousResultSize = PREVIOUS_RESULT_SIZE
params.nextResultSize = NEXT_RESULT_SIZE
params.reverse = REVERSE
params.messageType = MESSAGE_TYPE
params.customType = CUSTOM_TYPE
...

openChannel.getMessagesByTimestamp(TIMESTAMP, params: params, completionHandler: { (messages, error) in
    guard error == nil else {
        // 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

ArgumentDescription

TIMESTAMP

Type: long long
Specifies the timestamp to be the reference point of a retrieval, in Unix milliseconds.

IS_INCLUSIVE

Type: BOOL
Determines whether to include the messages sent exactly on the TIMESTAMP.

PREVIOUS_RESULT_SIZE

Type: NSInteger
Specifies the number of messages to retrieve, which are sent previously before a specified timestamp. Note that the actual number of results may be larger than the set value when there are multiple messages with the same timestamp as the earliest message.

NEXT_RESULT_SIZE

Type: NSInteger
Specifies the number of messages to retrieve, which are sent later after a specified timestamp. Note that the actual number of results may be larger than the set value when there are multiple messages with the same timestamp as the latest message.

REVERSE

Type: BOOL
Determines whether to sort the retrieved messages in reverse order.

MESSAGE_TYPE

Type: SBDMessageTypeFilter
Specifies the message type to filter the messages with the corresponding type. Acceptable values are SBDMessageTypeFilterAll, SBDMessageTypeFilterUser, SBDMessageTypeFilterFile, and SBDMessageTypeFilterAdmin.

CUSTOM_TYPE

Type: NSString
Specifies the custom message type to filter the messages with the corresponding custom type.

You can also retrieve a set number of previous and next messages on both sides of a specific message ID in an open channel, using the getMessagesByMessageId:params:completionHandler: method and SBDMessageListParams object.

Objective-C
Swift
Light Color Skin
Copy
SBDMessageListParams *params = [[SBDMessageListParams alloc] init];
[params setIsInclusive:IS_INCLUSIVE];
[params setPreviousResultSize:PREVIOUS_RESULT_SIZE];
[params setNextResultSize:NEXT_RESULT_SIZE];
[params setReverse:REVERSE];
[params setMessageType:MESSAGE_TYPE];
[params setCustomType:CUSTOM_TYPE];
...

[openChannel 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
var params = SBDMessageListParams()
params.isInclusive = IS_INCLUSIVE
params.previousResultSize = PREVIOUS_RESULT_SIZE
params.nextResultSize = NEXT_RESULT_SIZE
params.reverse = REVERSE
params.messageType = MESSAGE_TYPE
params.customType = CUSTOM_TYPE
...

openChannel.getMessages(byMessageId: MESSAGE_ID, params: params, completionHandler: { (messages, error) in
    guard error == nil else {
        // 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

ArgumentDescription

MESSAGE_ID

Type: long long
Specifies the unique ID of the message to be the reference point of a retrieval.

IS_INCLUSIVE

Type: BOOL
Determines whether to include the message identified with a specified message ID.

PREVIOUS_RESULT_SIZE

Type: NSInteger
Specifies the number of messages to retrieve, which are sent previously before a specified message ID.

NEXT_RESULT_SIZE

Type: NSInteger
Specifies the number of messages to retrieve, which are sent later after a specified timestamp.

REVERSE

Type: BOOL
Determines whether to sort the retrieved messages in reverse order.

MESSAGE_TYPE

Type: SBDMessageTypeFilter
Specifies the message type to filter the messages with the corresponding type. Acceptable values are SBDMessageTypeFilterAll, SBDMessageTypeFilterUser, SBDMessageTypeFilterFile, and SBDMessageTypeFilterAdmin.

CUSTOM_TYPE

Type: NSString
Specifies the custom message type to filter the messages with the corresponding custom type.


List messages along with their replies

The loadPreviousMessagesWithLimit:reverse:completionHandler:, getMessagesByTimestamp:params:completionHandler: or getMessagesByMessageId:params:completionHandler: methods can be used to retrieve messages and their replies in a specific thread.

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, change the value of the includeReplies property set to YES.

Objective-C
Swift
Light Color Skin
Copy
SBDPreviousMessageListQuery *listQuery = [openChannel createPreviousMessageListQuery];
listQuery.includeReplies = INCLUDE_REPLIES;
listQuery.includeThreadInfo = INCLUDE_THREAD_INFO;
listQuery.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT;
...

// This retrieves previous messages.
[listQuery loadPreviousMessagesWithLimit:LIMIT reverse:REVERSE completionHandler:^(NSArray * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
let listQuery = openChannel!.createPreviousMessageListQuery()
listQuery!.includeReplies = INCLUDE_REPLIES
listQuery!.includeThreadInfo = INCLUDE_THREAD_INFO
listQuery!.includeParentMessageText = INCLUDE_PARENT_MESSAGE_TEXT
...

// This retrieves previous messages.
listQuery?.loadPreviousMessages(withLimit: LIMIT, reverse: REVERSE, completionHandler: { (messages, error) in
    if error != nil {
        // Handle error.
    }

    ...
})

List of arguments

ArgumentDescription

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.

INCLUDE_REPLIES

Type: BOOL
Determines whether to include replies in the results.

INCLUDE_THREAD_INFO

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

INCLUDE_PARENT_MESSAGE_TEXT

Type: 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.

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.

When using either of the methods above, you can also pass a SBDMessageListParams object as an argument to the parameter in those methods.

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

List of properties

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.

By timestamp

The getMessagesByTimestamp:params:completionHandler: method returns 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
[openChannel 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
openChannel?.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

ArgumentDescription

TIMESTAMP

Type: 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

The getMessagesByMessageId:params:completionHandler: method returns 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
[openChannel 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
openChannel?.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

ArgumentDescription

MESSAGE_ID

Type: 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

With the timestamp of the parent message, you can retrieve a single message with its replies by creating and passing a SBDThreadedMessageListParams object into the getThreadedMessagesByTimestamp:params:completionHandler: method as an argument.

Objective-C
Swift
Light Color Skin
Copy
// Create a `SBDThreadedMessageListParams` object.
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;
...

// Pass the params to the parameter in the `getThreadedMessagesByTimestamp:params:completionHandler:` method.
[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
// Create a `SBDThreadedMessageListParams` object.
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
...

// Pass the params to the parameter in the `getThreadedMessagesByTimestamp:params:completionHandler:` method.
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

ArgumentDescription

TIMESTAMP

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

PREV_RESULT_SIZE

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

NEXT_RESULT_SIZE

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

INCLUSIVE

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.

INCLUDE_PARENT_MESSAGE_TEXT

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.


Retrieve a message

You can retrieve a specific message by creating and passing the SBDMessageRetrievalParams object as an argument into the getMessageWithParams:completionHandler: method.

Objective-C
Swift
Light Color Skin
Copy
// Create a `SBDMessageRetrievalParams` object.
SBDMessageRetrievalParams *params = [[SBDMessageRetrievalParams alloc] init];
params.messageId = MESSAGE_ID;
params.channelType = CHANNEL_TYPE;
params.channelUrl = CHANNEL_URL;
...

// Pass the params to the parameter of the `getMessageWithParams:completionHandler:` method.
[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
// Create a `SBDMessageRetrievalParams` object.
let params = SBDMessageRetrievalParams()
params.messageId = MESSAGE_ID
params.channelType = CHANNEL_TYPE
params.channelUrl = CHANNEL_URL
...

// Pass the params to the parameter of the `getMessageWithParams:completionHandler:` method.
SBDBaseMessage.getWith(params) { (message, error) in
    if error != nil {
        // Handle error.
    }

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

List of arguments

ArgumentDescription

MESSAGE_ID

Type: long long
Specifies the unique ID of the message to retrieve.

CHANNEL_TYPE

Type: SBDChannelType
Specifies the type of the channel.

CHANNEL_URL

Type: NSString
Specifies the URL of the channel to retrieve the message.


Update a message

A user can update any of their own text and file messages sent. An error is returned if a user attempts to update another user's messages. In addition, channel operators can update any messages sent in the channel.

Objective-C
Swift
Light Color Skin
Copy
// For a text message
SBDUserMessageParams *params = [[SBDUserMessageParams alloc] initWithMessage:NEW_TEXT_MESSAGE];
params.customType = NEW_CUSTOM_TYPE;
params.data = NEW_DATA;

// The USER_MESSAGE_ID below indicates the unique message ID of a UserMessage object to update.
[openChannel updateUserMessageWithMessageId:USER_MESSAGE_ID userMessageParams:params completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The message is successfully updated.
    // Through the "userMessage" parameter of the callback method,
    // you could check if the update operation has been performed right.
    NSString *text = userMessage.message;
    ...
}];

// For a file message
SBDFileMessageParams *params = [[SBDFileMessageParams alloc] initWithFileUrl:NEW_FILE_URL];
params.fileName = NEW_FILE_NAME;
params.fileSize = NEW_FILE_SIZE;
params.customType = NEW_CUSTOM_TYPE;

// The FILE_MESSAGE_ID below indicates the unique message ID of a FileMessage object to update.
[openChannel updateFileMessageWithMessageId:FILE_MESSAGE_ID fileMessageParams:params completionHandler:^(SBDFileMessage * _Nullable fileMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The message is successfully updated.
    // Through the "fileMessage" parameter of the callback method,
    // you could check if the update operation has been performed right.
    NSString *customType = fileMessage.customType;
    ...
}];
Light Color Skin
Copy
// For a text Message
var params = SBDUserMessageParams(message: NEW_TEXT_MESSAGE)
params.customType = NEW_CUSTOM_TYPE
params.data = NEW_DATA

// The USER_MESSAGE_ID below indicates the unique message ID of a UserMessage object to update.
openChannel.updateUserMessage(withMessageId: USER_MESSAGE_ID, userMessageParams: params, completionHandler: { (userMessage, error) in
    guard error == nil else {
        // Handle error.
    }

    // The message is successfully updated.
    // Through the "userMessage" parameter of the callback method,
    // you could check if the update operation has been performed right.
    let text = userMessage?.message
    ...
})

// For a file message
var params = SBDFileMessageParams(fileUrl: NEW_FILE_URL)
params.fileName = NEW_FILE_NAME
params.fileSize = NEW_FILE_SIZE
params.customType = NEW_CUSTOM_TYPE

// The FILE_MESSAGE_ID below indicates the unique message ID of a FileMessage object to update.
openChannel.updateFileMessage(withMessageId: FILE_MESSAGE_ID, fileMessageParams: params, completionHandler: { (fileMessage, error) in
    guard error == nil else {
        // Handle error.
    }

    // The message is successfully updated.
    // Through the "fileMessage" parameter of the callback method,
    // you could check if the update operation has been performed right.
    let customType = fileMessage?.customType
    ...
})

If a message is updated, the channel:didUpdateMessage: method in the channel delegate will be invoked on all channel participants' devices except the one that updated the message.

Objective-C
Swift
Light Color Skin
Copy
@interface OpenChannelChattingViewController : UIViewController

@end

@implementation OpenChannelChattingViewController

- (void)initOpenChannelChattingViewController {
    [SBDMain addChannelDelegate:self identifier:UNIQUE_DELEGATE_ID];
}

- (void)channel:(SBDBaseChannel *)sender didUpdateMessage:(SBDBaseMessage *)message {
    ...
}

@end
Light Color Skin
Copy
class OpenChannelChattingViewController: UIViewController, SBDChannelDelegate {
    SBDMain.add(self, identifier: self.delegateIdentifier)

    func channel(_ sender: SBDBaseChannel, didUpdate message: SBDBaseMessage) {
        ...
    }
}

Delete a message

A user can delete any messages sent by themselves. An error is returned if a user attempts to delete the messages of other participants. Also operators of an open channel can delete any messages in a channel.

Objective-C
Swift
Light Color Skin
Copy
// The BASE_MESSAGE below indicates a BaseMessage object to delete.
[openChannel deleteMessage:BASE_MESSAGE completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The message is successfully deleted from the channel.
    ...
}];
Light Color Skin
Copy
// The BASE_MESSAGE below indicates a BaseMessage object to delete.
openChannel.delete(BASE_MESSAGE, completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    // The message is successfully deleted from the channel.
    ...
})

If a message is deleted, the channel:messageWasDeleted: method in the channel delegate will be invoked on all channel participants' devices including the one that deleted the message.

Objective-C
Swift
Light Color Skin
Copy
@interface OpenChannelChattingViewController : UIViewController

@implementation OpenChannelChattingViewController

- (void)initOpenChannelChattingViewController {
    [SBDMain addChannelDelegate:self identifier:UNIQUE_DELEGATE_ID];
}

- (void)channel:(SBDBaseChannel * _Nonnull)sender messageWasDeleted:(long long)messageId {
    ...
}

@end
Light Color Skin
Copy
class OpenChannelChattingViewController: UIViewController, SBDChannelDelegate {
    SBDMain.add(self, identifier: self.delegateIdentifier)

    func channel(_ sender: SBDBaseChannel, messageWasDeleted messageId: Int64) {
        ...
    }
}

Copy a message

A user can copy and send their own message in the same channel or to another channel.

User message

Objective-C
Swift
Light Color Skin
Copy
[openChannel copyUserMessage:MESSAGE_TO_COPY toTargetChannel:TARGET_CHANNEL completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The message is successfully copied to the target channel.
    ...
}];
Light Color Skin
Copy
openChannel.copyUserMessage(MESSAGE_TO_COPY, toTargetChannel:TARGET_CHANNEL, completionHandler: { (userMessage, error) in
    guard error == nil else {
        // Handle error.
    }

    // The message is successfully copied to the target channel.
    ...
})

File message

Objective-C
Swift
Light Color Skin
Copy
[openChannel copyFileMessage:MESSAGE_TO_COPY toTargetChannel:TARGET_CHANNEL completionHandler:^(SBDUserMessage * _Nullable fileMessage, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The message is successfully copied to the target channel.
    ...
}];
Light Color Skin
Copy
openChannel.copyFileMessage(MESSAGE_TO_COPY, toTargetChannel:TARGET_CHANNEL, completionHandler: { (fileMessage, error) in
    guard error == nil else {
        // Handle error.
    }

    // The message is successfully copied to the target channel.
    ...
})

List of arguments

ArgumentTypeDescription

MESSAGE_TO_COPY

object

Specifies a message to copy.

TARGET_CHANNEL

object

Specifies a target channel to send a copied message to.

COMPLETION_HANDLER

handler

Specifies the callback handler to receive the response from Sendbird server for a message copy request.


Retrieve a list of participants

You can retrieve a list of participants who are currently online and receiving all messages from an open channel.

Objective-C
Swift
Light Color Skin
Copy
SBDParticipantListQuery *listQuery = [openChannel createParticipantListQuery];

[listQuery loadNextPageWithCompletionHandler:^(NSArray * _Nullable participants, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
let listQuery = openChannel.createParticipantListQuery()

listQuery?.loadNextPage(completionHandler: { (participants, error) in
    if error != nil {
        // Handle error.
    }

    ...
})

Retrieve the latest information on participants

To retrieve the latest and updated information on each online participant in an open channel, you need another SBDParticipantListQuery instance for the channel. Like the Retrieve a list of participants section above, create a new query instance using the createParticipantListQuery(), and then call its loadNextPageWithCompletionHandler: method consecutively to retrieve the latest.

You can also retrieve the latest and updated information on users at the application level. Like the Retrieve a list of users section, create a SBDApplicationUserListQuery instance using the SBDMain's createApplicationUserListQuery(), and then call its loadNextPageWithCompletionHandler: method consecutively to retrieve the latest.

When retrieving the online (connection) status of a user, by checking the connectionStatus of each SBDUser object in a returned list, you can get the user's current connection status. The connectionStatus has one of the following two values:

Objective-C

ValueDescription

SBDUserConnectionStatusOffline

The user is not connected to Sendbird server.

SBDUserConnectionStatusOnline

The user is connected to Sendbird server.

Swift

ValueDescription

SBDUserConnectionStatus.offline

The user is not connected to Sendbird server.

SBDUserConnectionStatus.online

The user is connected to Sendbird server.

Note: If you need to keep track of the connection status of some users in real time, we recommend that you call periodically the loadNextPageWithCompletionHandler: method of a SBDApplicationUserListQuery instance after specifying its userIdsFilter filter, perhaps in intervals of one minute or more.


Retrieve a list of operators

You can follow the simple implementation below to retrieve a list of operators who monitor and control the activities in an open channel.

Objective-C
Swift
Light Color Skin
Copy
[SBDOpenChannel getChannelWithUrl:CHANNEL_URL completionHandler:^(SBDOpenChannel * _Nullable openChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // Retrieving operators.
    for (SBDUser *operator in openChannel.operators) {
        ...
    }
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL, completionHandler: { (openChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    // Retrieving operators.
    for operator in openChannel.operators {
        ...
    }
})

You can also create a SBDOperatorListQuery instance and use the loadNextPageWithCompletionHandler: method to retrieve the list like the following.

Objective-C
Swift
Light Color Skin
Copy
SBDOperatorListQuery *listQuery = [openChannel createOperatorListQuery];

[listQuery loadNextPageWithCompletionHandler:^(NSArray * _Nullable users, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // Retrieving operators.
    for (SBDUser *operator in users) {
        ...
    }
}];
Light Color Skin
Copy
let listQuery = openChannel.createOperatorListQuery()

listQuery?.loadNextPage(completionHandler: { (users, error) in
    guard error == nil else {
        // Handle error.
    }

    // Retrieving operators.
    for operator in users! {
        ...
    }
})

Register operators

You can register participants as an operator of an open channel.

Objective-C
Swift
Light Color Skin
Copy
[openChannel addOperatorsWithUserIds:@[USER_ID_1, USER_ID_2] completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The participants are successfully registered as operators of the channel.
    ...
}];
Light Color Skin
Copy
openChannel.addOperators(withUserIds: [USER_ID_1, USER_ID_2]) { (error) in
    guard error == nil else {
        // Handle error.
    }

    // The participants are successfully registered as operators of the channel.
    ...
}

Cancel the registration of operators

You can cancel the registration of operators from an open channel but leave them as participants.

Objective-C
Swift
Light Color Skin
Copy
[openChannel removeOperatorsWithUserIds:@[USER_ID_1, USER_ID_2] completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The cancel operation is succeeded,
    // and you could display some message to those who are not operators anymore.
    ...
}];
Light Color Skin
Copy
openChannel.removeOperators(withUserIds: [USER_ID_1, USER_ID_2]) { (error) in
    guard error == nil else {
        // Handle error.
    }

    // The cancel operation is succeeded,
    // and you could display some message to those who are not operators anymore.
    ...
}

If you want to cancel the registration of all operators in a channel at once, use the following code.

Objective-C
Swift
Light Color Skin
Copy
[openChannel removeAllOperatorsWithCompletionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
openChannel.removeAllOperators { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
}

Retrieve a list of banned or muted users

You can create a query to retrieve a list of banned or muted users from an open channel. This query is only available for users who are registered as operators of an open channel.

Objective-C
Swift
Light Color Skin
Copy
// Retrieving banned users.
SBDBannedUserListQuery *listQuery = [openChannel createBannedUserListQuery];

[listQuery loadNextPageWithCompletionHandler:^(NSArray * _Nullable users, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];

// Retrieving muted users.
SBDMutedUserListQuery *listQuery = [openChannel createMutedUserListQuery];

[listQuery loadNextPageWithCompletionHandler:^(NSArray * _Nullable users, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
// Retrieving banned users.
let listQuery = openChannel.createBannedUserListQuery()

listQuery?.loadNextPage(completionHandler: { (users, error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

// Retrieving muted users.
let listQuery = openChannel.createMutedUserListQuery()

listQuery?.loadNextPage(completionHandler: { (users, error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

Ban and unban a user

Operators of an open channel can remove any users that behave inappropriately in the channel by using our Ban feature. Banned users are immediately expelled from a channel and allowed to participate in the channel again after the time period set by the operators. Operators can ban and unban users from open channels using the following code.

Objective-C
Swift
Light Color Skin
Copy
[SBDOpenChannel getChannelWithUrl:CHANNEL_URL completionHandler:^(SBDOpenChannel * _Nullable openChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    if ([openChannel isOperatorWithUser:[SBDMain getCurrentUser]]) {
        // Ban a user.
        [openChannel banUser:USER seconds:SECONDS completionHandler:^(SBDError * _Nullable error) {
            if (error != nil) {
                // Handle error.
            }

            // The user is successfully banned from the channel.
            // You could notify the user of being banned by displaying a prompt.
            ...
        }];

        // Unban a user.
        [openChannel unbanUser:USER completionHandler:^(SBDError * _Nullable error) {
            if (error != nil) {
                // Handle error.
            }

            // The user is successfully unbanned for the channel.
            // You could notify the user of being unbanned by displaying a prompt.
            ...
        }];
    }
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL, completionHandler: { (openChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    if openChannel!.isOperator(with: SBDMain.getCurrentUser()!) {
        // Ban a user.
        openChannel?.ban(USER, seconds: SECONDS, completionHandler: { (error) in
            guard error == nil else {
                // Handle error.
            }

            // The user is successfully banned from the channel.
            // You could notify the user of being banned by displaying a prompt.
            ...
        })

        // Unban a user.
        openChannel?.unbanUser(USER, completionHandler: { (error) in
            guard error == nil else {
                // Handle error.
            }

            // The user is successfully unbanned for the channel.
            // You could notify the user of being unbanned by displaying a prompt.
            ...
        })
    }
})

Note: Instead of banUser:seconds:completionHandler: and unbanUser:completionHandler: methods, you can use banUserWithUserId:seconds:completionHandler: and unbanUserWithUserId:completionHandler:, as they have the same functionalities.


Mute and unmute a user

Operators of an open channel can prohibit selected users from sending messages using our Mute feature. Muted users remain in the channel and are allowed to view the messages, but can't send any messages until the operators unmute them. Operators can mute and unmute users in open channels using the following code:

Objective-C
Swift
Light Color Skin
Copy
[SBDOpenChannel getChannelWithUrl:CHANNEL_URL completionHandler:^(SBDOpenChannel * _Nullable openChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    if ([openChannel isOperatorWithUser:[SBDMain getCurrentUser]]) {
        // Mute a user.
        [openChannel muteUser:USER completionHandler:^(SBDError * _Nullable error) {
            if (error != nil) {
                // Handle error.
            }

            // The user is successfully muted in the channel.
            // You could notify the user of being muted by displaying a prompt.
            ...
        }];

        // Unmute a user.
        [openChannel unmuteUser:USER completionHandler:^(SBDError * _Nullable error) {
            if (error != nil) {
                // Handle error.
            }

            // The user is successfully unmuted in the channel.
            // You could notify the user of being unmuted by displaying a prompt.
            ...
        }];
    }
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL, completionHandler: { (openChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    if openChannel?.isOperator(with: USER) ?? false {
        // Mute a user.
        openChannel?.muteUser(USER, completionHandler: { (error) in
            guard error == nil else {
                // Handle error.
            }

            // The user is successfully muted in the channel.
            // You could notify the user of being muted by displaying a prompt.
            ...
        })

        // Unmute a user.
        openChannel?.unmuteUser(USER, completionHandler: { (error) in
            guard error == nil else {
                // Handle error.
            }

            // The user is successfully unmuted in the channel.
            // You could notify the user of being unmuted by displaying a prompt.
            ...
        })
    }
})

Note: Instead of muteUser:completionHandler: and unmuteUser:completionHandler:methods, you can also use muteUserWithUserId:completionHandler: and unmuteUserWithUserId:completionHandler:, as they have the same functionalities.


Report a message, a user, or a channel

In an open channel, a user can report suspicious or harassing messages as well as the other users who use abusive language. The user can also report channels if there are any inappropriate content or activity within the channel. Based on this feature and our report API, you can build your own in-app system for managing objectionable content and subject.

Objective-C
Swift
Light Color Skin
Copy
// Reporting a message.
[openChannel reportMessage:MESSAGE_TO_REPORT reportCategory:REPORT_CATEGORY reportDescription:DESCRIPTION completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];

// Reporting a user.
[openChannel reportUser:OFFENDING_USER reportCategory:REPORT_CATEGORY reportDescription:DESCRIPTION completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];

// Reporting a channel.
[openChannel reportWithCategory:REPORT_CATEGORY reportDescription:DESCRIPTION completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
// Reporting a message.
openChannel.report(message: MESSAGE_TO_REPORT, reportCategory: REPORT_CATEGORY, reportDescription: DESCRIPTION, completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

// Reporting a user.
openChannel.report(offendingUser: OFFENDING_USER, reportCategory: REPORT_CATEGORY, reportDescription: DESCRIPTION, completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

// Reporting a channel.
openChannel.report(withCategory: REPORT_CATEGORY, reportDescription: DESCRIPTION, completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

List of arguments

ArgumentTypeDescription

MESSAGE_TO_REPORT

object

Specifies the message to report for its suspicious, harassing, or inappropriate content.

OFFENDING_USER

object

Specifies the user who uses offensive or abusive language such as sending explicit messages or inappropriate comments.

REPORT_CATEGORY

enum

Specifies a report category which indicates the reason for reporting. Acceptable values are SBDReportCategorySuspicious, SBDReportCategoryHarassing, SBDReportCategoryInappropriate, and SBDReportCategorySpam.

DESCRIPTION

string

Specifies additional information to include in the report.