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 Application > Open channels panel, 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:DATA 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
    }
}
ParameterDescription

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 data that you can store for the channel.

OPERATOR_USERS

Type: NSArray
Specifies an array of one or more users to register as operators to 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, 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.

Note: When 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 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) { // 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 Application > 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;
    }

    // TODO: Implement what is needed with the contents of the response in the openChannel parameter.
}];
Light Color Skin
Copy
SBDOpenChannel.getWithUrl(CHANNEL_URL) { (openChannel, error) in
    guard error == nil else {   // Error.
        return
    }
    
    // TODO: Implement what is needed with the contents of the response in the openChannel parameter.
}

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:LIST_OF_USERS_TO_MENTION
[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 = LIST_OF_USERS_TO_MENTION
params.metaArrayKeys = ["linkTo", "itemType"]
params.targetLanguages = ["fr", "de"]           // French and German
params.pushNotificationDeliveryOption = SBDPushNotificationDeliveryOptionDefault

openChannel.sendUserMessage(with: params) { (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: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 setData:DATA];
[params setMentionType:SBDMentionTypeUsers];        // Either SBDMentionTypeUsers or SBDMentionTypeChannel
[params setMentionedUserIds:@[@"Jeff", @"Julia"]];  // Or setMentionedUsers:LIST_OF_USERS_TO_MENTION
[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 = 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.data = DATA
params.mentionType = SBDMentionTypeUsers        // Either SBDMentionTypeUsers or SBDMentionTypeChannel
params.mentionedUserIds = ["Jeff", "Julia"]     // Or .mentionedUsers = LIST_OF_USERS_TO_MENTION
params.metaArrayKeys = ["linkTo", "itemType"]
params.targetLanguages = ["fr", "de"]           // French and German
params.pushNotificationDeliveryOption = SBDPushNotificationDeliveryOptionDefault

openChannel.sendFileMessage(with: params) { (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 {
    // TODO: Implement what is needed with the contents of the response in the 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 as SBDChannelDelegate, identifier: self.delegateIdentifier)

    func channel(_ sender: SBDBaseChannel, didReceive message: SBDBaseMessage) {
        // TODO: Implement what is needed with the contents of the response in the 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)

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 *> *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) {     // Error.
        return;
    }
}];
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 {
    // TODO: Implement what is needed.
    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
// There should only be one single instance per channel view.
SBDPreviousMessageListQuery *previousMessageQuery = [openChannel createPreviousMessageListQuery];

...

// Retrieving previous messages
[previousMessageQuery loadPreviousMessagesWithLimit:LIMIT reverse:REVERSE completionHandler:^(NSArray<SBDBaseMessage *> * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }    
}];
Light Color Skin
Copy
// There should be only one single instance per channel.
let previousMessageQuery = openChannel.createPreviousMessageListQuery()

...

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

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 the reversed order. If true, returns a list of messages which the latest comes at first and the earlist at last. the results are sorted in the reversed order. If false, returns a list of messages which the earlist comes at first and the latest at last.

A LIMIT parameter indicates 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

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 the specified 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 the specified timestamp is successfully retrieved.
}
ParameterDescription

TIMESTAMP

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

LIMIT

Type: NSInteger
Specifies the number of messages to retrieve. 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

Type: BOOL
Determines whether to sort the retrieved messages in the reversed 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.

Note: To retrieve messages sent after a specific timestamp, use the getNextMessagesByTimestamp:limit:...: in a similar fashion. 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.
}
ParameterDescription

MESSAGE_ID

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

LIMIT

Type: NSInteger
Specifies the number of messages to retrieve. 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

Type: BOOL
Determines whether to sort the retrieved messages in the reversed 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.

Note: To retrieve messages sent after a specific message ID, use the getNextMessagesByMessageId:limit:...: in a similar fashion. 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
// 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) { // Error.
        return;
    }
}];

...

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

// 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) { // Error.
        return;
    }
}];
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) { (userMessage, error) in
    guard error == nil else {   // Error.
        return
    }
}

...

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

// The FILE_MESSAGE_ID below indicates the unique message ID of a FileMessage object to update.
openChannel.updateFileMessage(withMessageId: FILE_MESSAGE_ID, fileMessageParams: params) { (fileMessage, 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
// The BASE_MESSAGE below indicates a BaseMessage object to delete.
[openChannel deleteMessage:BASE_MESSAGE completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];
Light Color Skin
Copy
// The BASE_MESSAGE below indicates a BaseMessage object to delete.
self.openChannel.delete(BASE_MESSAGE) { (error) in
    guard error == nil else {   // 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.

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

// 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
// Retrieving banned users 
let bannedListQuery = openChannel.createBannedUserListQuery()
bannedListQuery?.loadNextPage(completionHandler: { (users, error) in
    guard error == nil else {   // Error.
        return
    }
})

// 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.


Report a message, a user, or a channel

In an open channel, a user can report suspicious or harrassing 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) {     // Error.
        return;
    }
}];

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

// Reporting a channel
[openChannel reportWithCategory:REPORT_CATEGORY reportDescription:DESCRIPTION completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {     // Error.
        return;
    }
}];
Light Color Skin
Copy
// Reporting a message
openChannel.reportMessage(MESSAGE_TO_REPORT, reportCategory: REPORT_CATEGORY, reportDescription: DESCRIPTION, completionHandler: { (error) in
    guard error == nil else {   // Error.
        return
    }
})

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

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

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.