iOS
Open Channel

Open Channel

An open channel is basically a public chat and it can handle a large number of participants online. In this channel type, anyone can enter and participate in the chat without permission. A single open channel can accomodate up to 1,000, simultaneous users like Twitch-style public chat. This maximum number of an open channel's participants can increase per request.


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 Moderation > Open Channels menu, and then click Create Channel at the top-right corner.
  2. In the dialog box that appears, specify the name, URL, cover image, and custom type of a channel (the channel URL is a unique identifier.)

You can also create a channel on demand or dynamically via the SDK or the Platform 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) { // Error.
        return;
    }
}];
Light Color Skin
Copy
SBDOpenChannel.createChannel(withName: NAME, coverUrl: COVER_URL, data: DATA, operatorUsers: OPERATOR_USERS, completionHandler: { (openChannel, error) in
    guard error == nil else {   // Error.
        return
    }
})

When creating a channel, you can also append additional information like cover image and description by specifying several parameters.

Objective-C
Swift
Light Color Skin
Copy
[SBDOpenChannel createChannelWithName:NAME coverImage:COVER_IMAGE coverImageName:@"" data:nil operatorUsers:OPERATOR_USERS customType:CUSTOM_TYPE progressHandler:nil completionHandler:^(SBDOpenChannel * _Nullable openChannel, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];
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 {   // Error.
        return
    }
}
  • NAME: the name of a channel, or the channel topic.
  • COVER_IMAGE: the file of the cover image, which you can fetch to render into the UI. Alternatively, you can pass a URL of an image by changing coverImage to coverUrl.
  • DATA: the NSString field to store structured information, such as a JSON string.
  • OPERATOR_USERS: the list of users who are registered as operators of the channel.
  • CUSTOM_TYPE: the NSString field that allows you to subclassify your channel.

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, which are valid only within a current connection. So when a user is disconnected with the disconnectWithCompletionHandler: and reconnected to SendBird server with the connectWithUserId:, you should make sure the user re-enters the channels for them to continue receiving messages. (In case that a user is reconnected by attempts of the SendBird instance from a temporary unstable connection, the user is automatically re-entered into the participating channels.)

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

    [openChannel enterChannelWithCompletionHandler:^(SBDError * _Nullable error) {
        if (error != nil) { // Error.
            return;
        }
    }];
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL) { (openChannel, error) in
    guard error == nil else {   // Error. 
        return
    }

    openChannel?.enter(completionHandler: { (error) in
        guard error == nil else {   // Error.
            return
        }
    })
}

Exit a channel

If a user exit 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) { // Error. 
        return;
    }
    
    [openChannel exitChannelWithCompletionHandler:^(SBDError * _Nullable error) {
        if (error != nil) { // Error.
            return;
        }
    }];
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL) { (openChannel, error) in
    guard error == nil else {   // Error.
        return
    }

    openChannel?.exitChannel(completionHandler: { (error) in
        guard error == nil else {   // Error.
            return
        }
    })
}

Freeze and unfreeze a channel

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

To freeze, go to your dashboard and do the following: on the Moderation > Open Channels panel, select an open channel to freeze, and click the Freeze icon at the upper right corner. To unfreeze, click the icon again with the frozen channel selected.

  • In a frozen channel, participants can't chat one another but the operators can send a message to the channel.

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 *query = [SBDOpenChannel createOpenChannelListQuery];
[query loadNextPageWithCompletionHandler:^(NSArray<SBDOpenChannel *> * _Nullable openChannels, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];
Light Color Skin
Copy
let query = SBDOpenChannel.createOpenChannelListQuery()!
query.loadNextPage(completionHandler: { (openChannels, error) in
    guard error == nil else {   // Error.
        return
    }
})

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) { // Error!
        return;
    }

    // Successfully retrieving an open channel.
    // Do something with the channel.
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL) { (openChannel, error) in
    guard error == nil else {   // Error.
        return
    }

    // Successfully retrieving an open channel.
    // Do something with the channel.
}

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:

  • UserMessage: a text message sent by a user.
  • FileMessage: a binary file message sent by a user.

You can additionally specify a CUSTOM_TYPE to further subclassify a message. When you send a text message, you can attach arbitrary strings via a DATA field. You can utilize this field to send structured data such as font sizes, font types, or custom JSON objects.

Message delivery failures due to the network issues return an exception. By implementing the completionHandler of the method, you can display messages that are successfully sent to a channel.

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:
[params setMetaArrayKeys:@[@"linkTo", @"itemType"]];
[params setTargetLanguages:@[@"fr", @"de"]];        // French and German
[params setPushNotificationDeliveryOption:SBDPushNotificationDeliveryOptionDefault];

[openChannel sendUserMessageWithParams:params completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];
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
params.metaArrayKeys = ["linkTo", "itemType"]
params.targetLanguages = ["fr", "de"]           // French and German
params.pushNotificationDeliveryOption = SBDPushNotificationDeliveryOptionDefault

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

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

Sending a raw file indicates that you upload it to SendBird server and it can be downloaded from the server when needed in client apps. As another option, you can choose to send a file hosted on your server by passing a URL that represents the location of the file as a parameter. In this case, your file isn't hosted on SendBird server, and can be downloaded only from your own server instead.

Note: If you upload a file directly, a size limit is imposed per file depending on your plan. You can see your limit in the dashboard and adjust the limit via our sales team. No file size limit is imposed if you send a file message with its URL since the file isn't uploaded to SendBird server.

Objective-C
Swift
Light Color Skin
Copy
// Sending a file message with a raw file
NSMutableArray<SBDThumbnailSize *> *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: (You can 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 setData:DATA];
[params setMentionType:SBDMentionTypeUsers];        // Either SBDMentionTypeUsers or SBDMentionTypeChannel
[params setMentionedUserIds:@[@"Jeff", @"Julia"]];  // or setMentionedUsers:
[params setMetaArrayKeys:@[@"linkTo", @"itemType"]];
[params setTargetLanguages:@[@"fr", @"de"]];        // French and German
[params setPushNotificationDeliveryOption:SBDPushNotificationDeliveryOptionDefault];

[openChannel sendFileMessageWithParams:params completionHandler:^(SBDFileMessage * _Nonnull fileMessage, SBDError * _Nullable error) {
    if (error != nil) {     // Error.
        return;
    }
}];
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 (You can 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.data = DATA
params.mentionType = SBDMentionTypeUsers        // Either SBDMentionTypeUsers or SBDMentionTypeChannel
params.mentionedUserIds = ["Jeff", "Julia"]     // or .mentionedUsers
params.metaArrayKeys = ["linkTo", "itemType"]
params.targetLanguages = ["fr", "de"]           // French and German
params.pushNotificationDeliveryOption = SBDPushNotificationDeliveryOptionDefault

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

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()
    }
}   

Receive messages through a channel delegate

Messages can be received through the didReceiveMessage: method of a SBDChannelDelegate. A SBDBaseMessage object for each received message is one of the following three types.

  • 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 Platform API.

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

Objective-C
Swift
Light Color Skin
Copy
@interface OpenChannelViewController : ViewController<SBDChannelDelegate>

@end

@implementation OpenChannelChattingViewController

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


- (void)channel:(SBDBaseChannel * _Nonnull)sender didReceiveMessage:(SBDBaseMessage * _Nonnull)message {
    if (message isKindOfClass:[SBDUserMessage class]]) {
        // Do something when the received message is a UserMessage.
    }
    else if (message isKindOfClass:[SBDFileMessage class]]) {
        // Do something when the received message is a FileMessage.
    }
    else if (message isKindOfClass:[SBDAdminMessage class]]) {
        // Do something when the received message is an AdminMessage.
    }
}

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

    func channel(_ sender: SBDBaseChannel, didReceive message: SBDBaseMessage) {
        if message is SBDUserMessage {
            // Do something when the received message is a UserMessage.
        }
        else if message is SBDFileMessage {
            // Do something when the received message is a FileMessage.
        }
        else if message is SBDAdminMessage {
            // Do something when the received message is an AdminMessage.
        }
    }
}

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)

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<NSString *> *mentionedUserIds = [[NSMutableArray alloc] init];
[mentionedUserIds addObject:@"John"];
[mentionedUserIds addObject:@"Jay"];
[mentionedUserIds addObject:@"Jin"];

SBDUserMessageParams *params = [[SBDUserMessageParams alloc] initWithMessage:@"MENTION_1"];
...
[params setMentionedUserIds:mentionedUserIds];

[openChannel sendUserMessageWithParams:params completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
    if (error != nil) {     // Error.
        return;
    }
}];
Light Color Skin
Copy
var mentionedUserIds: [String] = []
mentionedUserIds.append("John")
mentionedUserIds.append("Jay")
mentionedUserIds.append("Jin")

let params = SBDUserMessageParams(message: "MENTION_1")
params?.mentionedUserIds = mentionedUserIds

guard let paramsBinded: SBDUserMessageParams = params else {
    // do something
    return
}

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

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
SBDPreviousMessageListQuery *previousMessageQuery = [openChannel createPreviousMessageListQuery];
[previousMessageQuery loadPreviousMessagesWithLimit:30 reverse:YES completionHandler:^(NSArray<SBDBaseMessage *> * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }    
}];
Light Color Skin
Copy
let previousMessageQuery = openChannel.createPreviousMessageListQuery()
previousMessageQuery?.loadPreviousMessages(withLimit: 30, reverse: true, completionHandler: { (messages, error) in
    guard error == nil else {   // Error.
        return
    }
})

A withLimit parameter (30 in the above sample code) indicates how many messages should be included in a list. A SBDPreviousMessageListQuery instance itself does pagination of a result set according to the value of the withLimit 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

You can retrieve a set number of messages sent previously before a specific timestamp in an open channel, using the getPreviousMessagesByTimestamp:limit:reverse:messageType:customType:completionHandler: method.

Objective-C
Swift
Light Color Skin
Copy
[openChannel getPreviousMessagesByTimestamp:TIMESTAMP limit:LIMIT reverse:REVERSE messageType:MESSAGE_TYPE customType:CUSTOM_TYPE completionHandler:^(NSArray<SBDBaseMessage *> * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }

    // A list of messages sent before timestamp is successfully retrieved.
}];
Light Color Skin
Copy
openChannel.getPreviousMessages(byTimestamp: TIMESTAMP, limit: LIMIT, reverse: REVERSE, messageType: MESSAGE_TYPE, customType: nil) { (messages, error) in
    guard error == nil else {   // Error.
        return
    }

    // A list of messages sent before timestamp is successfully retrieved.
}
  • TIMESTAMP (long): the timestamp to be the reference point of a retrieval, in Unix milliseconds.
  • LIMIT (int): the number of messages to load. 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.
  • REVERSE (boolean): whether or not to reverse the results.
  • MESSAGE_TYPE (enum): the message filtering option for the SBDMessageTypeFilter. The acceptable values are SBDMessageTypeFilterAll, SBDMessageTypeFilterUser, SBDMessageTypeFilterFile, or SBDMessageTypeFilterAdmin.
  • CUSTOM_TYPE (string): the custom message type to filter the messages with that custom type.

Note: To retrieve messages sent after a specific timestamp, use the getNextMessagesByTimestamp:limit:...: method in a similar way. You can also retrieve previous and next messages on both sides of a specific timestamp, using the getPreviousAndNextMessagesByTimestamp:prevLimit:nextLimit:...: method.

You can also retrieve a set number of messages sent previously before a specific message ID in an open channel, using the getPreviousMessagesByMessageId:limit:reverse:messageType:customType:completionHandler: method.

Objective-C
Swift
Light Color Skin
Copy
[openChannel getPreviousMessagesByMessageId:MESSAGE_ID limit:LIMIT reverse:REVERSE messageType:MESSAGE_TYPE customType:CUSTOM_TYPE completionHandler:^(NSArray<SBDBaseMessage *> * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) {     // Error.
        return;
    }

    // A list of messages, the IDs of which are ahead of the specified message ID, is successfully retrieved.
}];
Light Color Skin
Copy
openChannel.getPreviousMessages(byMessageId: MESSAGE_ID, limit: LIMIT, reverse: REVERSE, messageType: MESSAGE_TYPE, customType: CUSTOM_TYPE) { (messages, error) in
    guard error == nil else {       // Error.
        return
    }

    // A list of messages, the IDs of which are ahead of the specified message ID, is successfully retrieved.
}
  • MESSAGE_ID (long): the unique ID of the message to be the reference point of a retrieval.
  • LIMIT (int): the number of messages to load. 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.
  • REVERSE (boolean): whether or not to reverse the results.
  • MESSAGE_TYPE (enum): the message filtering option for the SBDMessageTypeFilter. The acceptable values are SBDMessageTypeFilterAll, SBDMessageTypeFilterUser, SBDMessageTypeFilterFile, or SBDMessageTypeFilterAdmin.
  • CUSTOM_TYPE (string): the custom message type to filter the messages with that custom type.

Note: To retrieve messages sent after a specific message ID, use the getNextMessagesByMessageId:limit:...: in a similar way. You can also retrieve previous and next messages on both sides of a specific message ID, using the getPreviousAndNextMessagesByMessageId:prevLimit:nextLimit:...: method.


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
// In case of UserMessage
[openChannel updateUserMessage:userMessage messageText:@"messageText" data:@"data" customType:@"customType" completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
    if (error != nil) {     // Error.
        return;
    }
}];

// In case of FileMessage
[openChannel updateFileMessage:fileMessage data:@"data" customType:@"customType" completionHandler:^(SBDFileMessage * _Nullable fileMessage, SBDError * _Nullable error) {
    if (error != nil) {     // Error.
        return;
    }
}];
Light Color Skin
Copy
// In case of UserMessage
self.openChannel.update(userMessage, messageText: "messageText", data: "data", customType: "customType") { (updatedUserMessage, error) in
    guard error == nil else {       // Error.
        return
    }
}

// In case of FileMessage
self.openChannel.update(fileMessage, data: "data", customType: "customType") { (updatedFileMessage, error) in
    guard error == nil else {       // Error.
        return
    }
}

The didUpdateMessage: method of a channel delegate will receive a callback from the server when a message is updated, and all participants of the channel will be notified, including who has updated their message.

Objective-C
Swift
Light Color Skin
Copy
@interface OpenChannelChattingViewController : ViewController<SBDChannelDelegate>

@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 as SBDChannelDelegate, 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
[openChannel deleteMessage:baseMessage completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];
Light Color Skin
Copy
self.openChannel.delete(baseMessage) { (error) in
    if error != nil {   // Error.
        return
    }
}

The messageWasDeleted: method of a channel delegate will receive a callback from the server when a message is deleted, and the result also notified to all other participants in the channel, including who has deleted their own message.

Objective-C
Swift
Light Color Skin
Copy
@interface OpenChannelChattingViewController : ViewController<SBDChannelDelegate>

@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 as SBDChannelDelegate, identifier: self.delegateIdentifier)
    
    func channel(_ sender: SBDBaseChannel, messageWasDeleted messageId: Int64) {
        
    }
}

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 *participantListQuery = [openChannel createParticipantListQuery];
[self.participantListQuery loadNextPageWithCompletionHandler:^(NSArray<SBDUser *> * _Nullable participants, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];
Light Color Skin
Copy
let participantListQuery = openChannel.createParticipantListQuery()
participantListQuery?.loadNextPage(completionHandler: { (participants, error) in
    if error != nil {   // Error.
        return
    }
})

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.

In case of 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
  • SBDUserConnectionStatusOffline: the user is not connected to SendBird server.
  • SBDUserConnectionStatusOnline: the user is connected to SendBird server.
Swift
  • 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) { // Error.
        return;
    }

    // Retrieving a list of operators.
    for (SBDUser *operator in openChannel.operators) {
        ... 
    }
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL) { (openChannel, error) in
    guard error == nil else {   // Error. 
        return
    }

    // Retrieving a list of operators.
    for var op in openChannel?.operators ?? NSMutableArray() {
        ...
    }
}

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
// In case of retrieving banned users 
SBDBannedUserListQuery *bannedListQuery = [openChannel createBannedUserListQuery];
[bannedListQuery loadNextPageWithCompletionHandler:^(NSArray<SBDUser *> * _Nullable users, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];

// In case of retrieving muted users 
SBDMutedUserListQuery *mutedListQuery = [openChannel createMutedUserListQuery];
[mutedListQuery loadNextPageWithCompletionHandler:^(NSArray<SBDUser *> * _Nullable users, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];
Light Color Skin
Copy
// In case of retrieving banned users 
let bannedListQuery = openChannel.createBannedUserListQuery()
bannedListQuery?.loadNextPage(completionHandler: { (users, error) in
    guard error == nil else {   // Error.
        return
    }
})

// In case of retrieving muted users 
let mutedListQuery = openChannel.createMutedUserListQuery()
mutedListQuery?.loadNextPage(completionHandler: { (users, error) in
    guard error == nil else {   // Error.
        return
    }
})

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) { // Error.
        return;
    }

    // Banning and unbanning a user 
    if ([openChannel isOperatorWithUser:[SBDMain getCurrentUser]]) {
        [openChannel banUser:USER seconds:SECONDS completionHandler:^(SBDError * _Nullable error) {
            if (error != nil) { // Error.
                return;
            }
        
            // Custom implementation for what to do after banning.
            }];

        [openChannel unbanUser:USER completionHandler:^(SBDError * _Nullable error) {
            if (error != nil) { // Error. 
                return;
            }

            // Custom implementation for what to do after unbanning.
        }];
    }
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL) { (openChannel, error) in
    guard error == nil else {   // Error. 
        return
    }

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

            // Custom implementation for what to do after banning.
        })
    
        openChannel?.unbanUser(USER, completionHandler: { (error) in
            guard error == nil else {   // Error.
                return
            }
            
            // Custom implementation for what to do after unbanning.
        })
    }
}

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


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) { // Error. 
        return;
    }
    
    // Muting and unmuting a user 
    if ([openChannel isOperatorWithUser:[SBDMain getCurrentUser]]) {
        [openChannel muteUser:USER completionHandler:^(SBDError * _Nullable error) {
            if (error != nil) { // Error. 
                return;
            }
            
            // Custom implementation for what to do after muting.
        }];

        [openChannel unmuteUser:USER completionHandler:^(SBDError * _Nullable error) {
            if (error != nil) { // Error.
                return;
            }
            
            // Custom implementation for what to do after unmuting.
        }];
    }
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL) { (openChannel, error) in
    guard error == nil else {   // Error.
        return
    }
    
    // Muting and unmuting a user 
    if openChannel?.isOperator(with: USER) ?? false {
        openChannel?.muteUser(USER, completionHandler: { (error) in
            guard error == nil else {   // Error.
                        return
                    }
            
            // Custom implementation for what to do after muting.
        })

        openChannel?.unmuteUser(USER, completionHandler: { (error) in
            guard error == nil else {   // Error. 
                return
            }

            // Custom implementation for what to do after unmuting.
        })
    }
}

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