Home
/
Chat
/
iOS

Group channel

A group channel is a chat that allows close interactions among a limited number of users. It can be private or public. A private group channel can let a user join the chat through an invitation by another user who is already a member of the chatroom. For 1-on-1 messaging, you can create a private group channel with two members. A public group chat can let a user join the chat without invitation from others. A group channel can consist of one to one hundred members by default setting. This default number of members can increase per request.

A user can receive all messages from the group channels that they are a member of, and sends a message to those channels. They can also receive push notifications, typing indicators, unread counts and read receipts from the joined channels when they go offline. For more information, see the Push notifications page which describes how to turn on and manage the push preference.


Choose a type of a channel

With our Chat SDK for iOS, you can use a variety of behaviour related properties when creating different types of group channels. You can create a group channel after configuring these properties.

Private vs. Public

A private group channel can be joined only by users that have accepted an invitation from an existing channel member by default. On the other hand, a public group channel can be joined by any user without an invitation, like an open channel.

1-on-1 vs. 1-on-N

The distinct option determines whether to resume an old channel or to create an entirely new one when someone attempts to open a new channel with a pre-existing member combination. If there is a group channel with those members, the attempt will re-start the existing channel that has their chat history. For example, when attempting to create a new group channel with 3 users, A, B, and C, if a channel with same users already exists, a reference to the existing channel is just returned to who has attempted the new channel.

Consequently, we recommend that you set the distinct option to YES in 1-on-1 messaging channels to reuse the existing channel when a user directly sends a message to another user. If the option is NO, a new group channel is created with the same user even if there is a previous chat between them, and you can't see the old messages or data.

Supergroup vs. Group

For occasions that demand engagement among a high volume of members, you can create a Supergroup channel, an expanded version of a group channel. When the super option is set to true, a Supergroup channel will be created and more than 2,000 members can gather in the channel. The maximum number of members in a Supergroup channel varies by your Sendbird plan.

Note: When the super option is set to YES or true, the distinct option can't be supported.

Ephemeral vs. Persistent

Messages sent in an ephemeral group channel are not saved in Sendbird's database. As such, old messages that are pushed out of a user's chat view due to new messages can't be retrieved. On the other hand, messages sent in a persistent group channel are stored permanently in the database by default.


Create a channel

A user can create a group channel from inviting other users anytime in their client app. At the implemention level, you just need to write your code which passes the IDs of users to invite as an argument to a parameter in the creation method.

Before you write the code for creating a group channel for a typical 1-on-1 chat, you should make sure that you turn on the distinct property of the channel. Otherwise, if you turn off the distinct property, a new channel will be created with the same partner user even if there is already an existing channel between them. In this case, multiple 1-on-1 channels between the same two users can exist, each with its own chat history and data.

However, if you plan to create a Supergroup channel, the distinct property should be turned off.

Note: If you want to retrieve a list of group channels, which also includes the current user's empty channels without any chat, you should set the includeEmptyChannel option of a SBDGroupChannelListQuery instance to YES for the retrieval.

Objective-C
Swift
Light Color Skin
Copy
[SBDGroupChannel createChannelWithUserIds:USER_IDS isDistinct:IS_DISTINCT completionHandler:^(SBDGroupChannel * _Nullable groupChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A group channel of the specified users is successfully created.
    // Through the "groupChannel" parameter of the callback method,
    // you can get the group channel's data from the result object that Sendbird server has passed to the callback method.
    NSString *channelUrl = groupChannel.channelUrl;
    ...
});
Light Color Skin
Copy
SBDGroupChannel.createChannel(withUserIds: USER_IDS, isDistinct: IS_DISTINCT, completionHandler: { (groupChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    // A group channel of the specified users is successfully created.
    // Through the "groupChannel" parameter of the callback method,
    // you can get the group channel's data from the result object that Sendbird server has passed to the callback method.
    let channelUrl = groupChannel?.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
[SBDGroupChannel createChannelWithName:NAME isDistinct:IS_DISTINCT userIds:USER_IDS coverUrl:COVER_IMAGE_URL data:DATA customType:CUSTOM_TYPE completionHandler:^(SBDGroupChannel * _Nullable groupChannel, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // A group channel with additional information is successfully created.
    NSString *channelUrl = groupChannel.channelUrl;
    ...
}];
Light Color Skin
Copy
SBDGroupChannel.createChannel(withName: NAME, isDistinct: IS_DISTINCT, userIds: USER_IDS, coverUrl: COVER_IMAGE_URL, data: DATA, customType: CUSTOM_TYPE, completionHandler: { (groupChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    // A group channel with additional information is successfully created.
    let channelUrl = groupChannel?.channelUrl
    ...
})
ArgumentDescription

NAME

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

IS_DISTINCT

Type: BOOL
Determines whether to reuse an existing channel or create a new channel. If set to YES, returns a channel with the same users in the USER_IDS or creates a new channel if no match is found. Sendbird server can also use the custom channel type in the CUSTOM_TYPE along with the USER_IDS to return the corresponding channel. If set to NO, Sendbird server always creates a new channel with a combination of the users as well as the channel custom type if specified.

IS_SUPER

Type: BOOL
Determines whethere a new channel will be a Supergroup channel or a group channel. If set to true, the new channel can accommodate more than 2,000 members. When this argument is true, IS_DISTINCT is not supperted and should be set to false.

USER_IDS

Type: NSArray
Specifies a list of one or more IDs of the users to invite to the channel.

COVER_IMAGE_URL

Type: NSString
Specifies the cover image URL of the channel.

DATA

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

CUSTOM_TYPE

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

You can get a cover image URL using the coverUrl property of a SBDGroupChannel object, and update the channel's cover image using a method like updateChannelWithName:isDistinct:coverUrl:data:completionHandler:.

Note: You can also create a group channel using Chat Platform API which helps you control channel creations and member invitations on your server-side.

Otherwise, you can configure SBDGroupChannelParams and create a new channel with that like below.

Objective-C
Swift
Light Color Skin
Copy
NSMutableArray<NSString *> *users = [[NSMutableArray alloc] init];
[users addObject:@"John"];
[users addObject:@"Harry"];
[users addObject:@"Jay"];

NSMutableArray<NSString *> *ops = [[NSMutableArray alloc] init];
[ops addObject:@"Jeff"];

SBDGroupChannelParams *params = [[SBDGroupChannelParams alloc] init];
[params setPublic:NO];
[params setEphemeral:NO];
[params setDistinct:NO];
[params setSuper:NO];
[params addUserIds:users];
[params setOperatorUserIds:ops];    // Or setOperators:
[params setName:@"NAME"];
[params setChannelUrl:@"UNIQUE_CHANNEL_URL"];   // In a group channel, you can create a new channel by specifying its unique channel URL in a 'SBDGroupChannelParams' object.
[params setCoverImage:FILE];        // Or setCoverUrl:
[params setData:@"DATA"];
[params setCustomType:@"CUSTOM_TYPE"];

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

    // A group channel with detailed configuration is successfully created.
    // By using groupChannel.channelUrl, groupChannel.members, groupChannel.data, groupChannel.customType, and so on,
    // you can access the result object from Sendbird server to check your SBDGroupChannelParams configuration.
    NSString *channelUrl = groupChannel.channelUrl;
    ...
}];
Light Color Skin
Copy
var users: [String] = []
users.append("John")
users.append("Harry")
users.append("Jay")

var ops: [String] = []
ops.append("Jeff")

var params = SBDGroupChannelParams()
params.isPublic = false
params.isEphemeral = false
params.isDistinct = false
params.isSuper = false
params.addUserIds(users)
params.operatorUserIds = ops        // Or .operators
params.name = NAME
params.channelUrl = UNIQUE_CHANNEL_URL  // In a group channel, you can create a new channel by specifying its unique channel URL in a 'GroupChannelParams' object.
params.coverImage = FILE            // Or .coverUrl
params.data = DATA
params.customType = CUSTOM_TYPE

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

    // A group channel with detailed configuration is successfully created.
    // By using groupChannel.channelUrl, groupChannel.members, groupChannel.data, groupChannel.customType, and so on,
    // you can access the result object from Sendbird server to check your SBDGroupChannelParams configuration.
    let channelUrl = groupChannel?.channelUrl
    ...
})

Invite users as members

Only members of a group channel can invite new users to the channel. You can also determine whether the newly invited user sees the past messages in the channel or not.

Note: In your dashboard, go to the Settings > Chat > Channels > Group channels, and there is the Chat history option. If the option is turned on, new users can view all messages sent before they have joined the channel. If turned off, new users only see messages sent after they have been invited. By default, this option is turned on.

Objective-C
Swift
Light Color Skin
Copy
NSMutableArray<NSString *> *userIds = [[NSMutableArray alloc] init];
[users addObject:@"Tyler"];
[users addObject:@"Young"];

[groupChannel inviteUserIds:userIds completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
var userIds: [String] = []
users.append("Tyler")
users.append("Young")

groupChannel.inviteUserIds(userIds, completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

Accept or decline an invitation from another user

A user who is invited to a group channel can accept or decline the invitation. If a user accepts an invitation, they join the channel as a new member and can start chatting with other members. Otherwise, the invitation will be canceled if a user declines it. Since a user is allowed to join up to 2,000 group channels, the invitation to a user who already belongs to a maximum number of group channels will be canceled automatically.

Objective-C
Swift
Light Color Skin
Copy
// Accepting an invitation
[groupChannel acceptInvitationWithCompletionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];

// Declining an invitation
[groupChannel declineInvitationWithCompletionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
// Accepting an invitation
groupChannel.acceptInvitation(completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

// Declining an invitation
groupChannel.declineInvitation(completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

By implementing the channel:didReceiveInvitation: and channel:didDeclineInvitation: in the channel delegate, you can make the client apps of other members in the foreground to be notified of the results of two actions above. If you want more information, see the Event delegate page.

Note: By using the setChannelInvitationAutoAccept:completionHandler:, you can determine for users within an application whether or not to automatically join a private group channel promptly from an invitation without having to accept it. By default, the value of channel invitation preference is YES. If you want to give them the option to decide whether to accept or decline an invitation, you should set the value of the preference to NO through the setChannelInvitationAutoAccept:completionHandler: like the following sample code.

Objective-C
Swift
Light Color Skin
Copy
BOOL autoAccept = NO;   // The value of YES (default) means that a user will automatically join a group channel with no choice of accepting and declining an invitation.
[SBDMain setChannelInvitationPreferenceAutoAccept:autoAccept completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
var autoAccept = false  // The value of true (default) means that a user will automatically join a group channel with no choice of accepting and declining an invitation.
SBDMain.setChannelInvitationPreferenceAutoAccept(autoAccept, completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

Join a channel as a member

This is only for public group channels. Any user can join a public group channel as a member without an invitation and chat with other members in the channel. Since a user is allowed to join up to 2,000 group channels, a user who already belongs to a maximum number of group channels can't join a new channel.

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

        // The current user successfully joins the group channel
        ...
    }];
}
Light Color Skin
Copy
if groupChannel.isPublic {
    groupChannel.join(completionHandler: { (error) in
        guard error == nil else {
            // Handle error.
        }

        // The current user successfully joins the group channel
        ...
    })
})

Leave a channel

If a user leaves a group channel, the user can't receive messages from the channel anymore.

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

    ...
}];
Light Color Skin
Copy
channel.leaveChannel(completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

Freeze and unfreeze a channel

You can temporarily disable various functions of a group channel to stop members from chatting in the channel, and enable the functions so that the members chat with each other. Note that in a frozen channel, normal members can't chat with each other but the operators can send a message to the channel.

Objective-C
Swift
Light Color Skin
Copy
// Freezing a channel
[groupChannel freezeWithCompletionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The channel successfully gets frozen.
    // You could display a message telling that chatting in the channel is unavailable, or do something in response to a successfull operation.
    ...
}];

// Unfreezing a channel
[groupChannel unfreezeWithCompletionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The channel successfully gets unfrozen.
    // You could display a message telling that chatting in the channel is available again, or do something in response to a successful operation.
    ...
}];
Light Color Skin
Copy
// Freezing a channel
groupChannel.freeze(completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    // The channel gets frozen.
    // You could display a message telling that chatting in the channel is unavailable, or do something in response to a successfull operation.
    ...
})

// Unfreezing a channel
groupChannel.unfreeze(completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    // The channel gets unfrozen.
    // You could display a message telling that chatting in the channel is available again, or do something in response to a successful operation.
    ...
})

Retrieve a list of channels

You can retrieve a list of the current user's private group channels using the loadNextPageWithCompletionHandler: method of a SDBGroupChannelListQuery instance, which returns a list of SBDGroupChannel objects.

Note: Using the includeEmptyChannel option of a SBDGroupChannelListQuery instance, you can determine whether to include empty channels in the result. Empty channels are group channels that have been created but do not contain any messages, and are not included by default. However, if you turn off the Chat history option in your dashboard, you may retrieve empty channels in the result.

Objective-C
Swift
Light Color Skin
Copy
SBDGroupChannelListQuery *listQuery = [SBDGroupChannel createMyGroupChannelListQuery];
listQuery.includeEmptyChannel = YES;
listQuery.memberStateFilter = SBDMemberStateFilterJoinedOnly;   // SBDMemberStateFilterAll, SBDMemberStateFilterJoinedOnly, SBDMemberStateFilterInvitedOnly, SBDMemberStateFilterInvitedByFriend, SBDMemberStatefilterInvitedByNonFriend
listQuery.order = SBDGroupChannelListOrderLatestLastMessage;    // SBDGroupChannelListOrderChronological, SBDGroupChannelListOrderLatestLastMessage, SBDGroupChannelListOrderChannelNameAlphabetical, and SBDGroupChannelListOrderChannelMetaDataValueAlphabetical
listQuery.limit = 15;

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

    // A list of matching group channels is successfully retrieved.
    // Through the "groupChannels" parameter of the callback method,
    // you can access the data of each group channel from the result list that Sendbird server has passed to the callback method.
    [self.channels addObjectsFromArray:groupChannels];
    ...
}];
Light Color Skin
Copy
let listQuery = SBDGroupChannel.createMyGroupChannelListQuery()
listQuery?.includeEmptyChannel = true
listQuery?.memberStateFilter = SBDMemberStateFilterJoinedOnly   // SBDMemberStateFilterAll, SBDMemberStateFilterJoinedOnly, SBDMemberStateFilterInvitedOnly, SBDMemberStateFilterInvitedByFriend, SBDMemberStatefilterInvitedByNonFriend
listQuery?.order = SBDGroupChannelListOrderLatestLastMessage    // SBDGroupChannelListOrderChronological, SBDGroupChannelListOrderLatestLastMessage, SBDGroupChannelListOrderChannelNameAlphabetical, and SBDGroupChannelListOrderChannelMetaDataValueAlphabetical
listQuery?.limit = 15

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

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

You can also retrieve a list of the current user's public group channels using the loadNextPageWithCompletionHandler: method of a SDBPublicGroupChannelListQuery instance, which returns a list of SBDGroupChannel objects.

Note: Using the includeEmptyChannel option of a SBDPublicGroupChannelListQuery instance, you can determine whether to include empty channels in the result. Empty channels are group channels that have been created but do not contain any messages, and are not included by default. However, if you turn off the Chat history option in your dashboard, you may retrieve empty channels in the result.

Objective-C
Swift
Light Color Skin
Copy
SBDPublicGroupChannelListQuery *listQuery = [SBDGroupChannel createPublicGroupChannelListQuery];
listQuery.includeEmptyChannel = YES;
listQuery.publicMembershipFilter = SBDPublicGroupChannelMembershipFilterJoined; // SBDPublicGroupChannelMembershipFilterAll, SBDPublicGroupChannelMembershipFilterJoined
listQuery.order = SBDPublicGroupChannelListOrderChannelNameAlphabetical;    // SBDPublicGroupChannelListOrderChronological, SBDPublicGroupChannelListOrderChannelNameAlphabetical, SBDPublicGroupChannelListOrderChannelMetaDataValueAlphabetical
listQuery.limit = 15;

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

    // A list of public group channels matching search criteria is successfully retrieved.
    // Through the "groupChannels" parameter of the callback method,
    // you can access the data of each group channel from the result list that Sendbird server has passed to the callback method.
    [self.channels addObjectsFromArray:groupChannels];
    ...
}];
Light Color Skin
Copy
let listQuery = SBDGroupChannel.createPublicGroupChannelListQuery()
listQuery?.includeEmptyChannel = true
listQuery?.publicMembershipFilter = SBDPublicGroupChannelMembershipFilterJoined // SBDPublicGroupChannelMembershipFilterAll, SBDPublicGroupChannelMembershipFilterJoined
listQuery?.order = SBDPublicGroupChannelListOrderChannelNameAlphabetical    // SBDPublicGroupChannelListOrderChronological, SBDPublicGroupChannelListOrderChannelNameAlphabetical, SBDPublicGroupChannelListOrderChannelMetaDataValueAlphabetical
listQuery?.limit = 15

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

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

Note: Refer to this section in the Advanced page for information on how to search for specific group channels with keywords and filters.


Retrieve a channel by URL

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

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

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

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

Note: We recommend that you store a user's channel URLs to handle the lifecycle or state changes of your client app, or 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.


Hide or archive a channel from a list of channels

The following code will allow you to hide or archive a specific group channel from a list of the channels.

Objective-C
Swift
Light Color Skin
Copy
// Hiding (archiving) a group channel.
[groupChannel hideChannelWithHidePreviousMessages:IS_HIDE_PREVIOUS_MESSAGES allowAutoUnhide:IS_ALLOW_AUTO_UNHIDE completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The channel successfully gets hidden from the list.
    // The current user's channel view should be refreshed to reflect the change.
    ...
}];

// Unhiding a group channel.
[groupChannel unhideChannelWithCompletionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // The channel successfully gets unhidden from the list.
    // The current user's channel view should be refreshed to reflect the change.
    ...
}];
Light Color Skin
Copy
// Hiding (archiving) a group channel.
groupChannel.hideChannel(withHidePreviousMessages:IS_HIDE_PREVIOUS_MESSAGES, allowAutoUnhide:IS_ALLOW_AUTO_UNHIDE, completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    // The channel successfully gets hidden from the list.
    // The current user's channel view should be refreshed to reflect the change.
    ...
})

// Unhiding a group channel.
groupChannel.unhideChannel(completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    // The channel successfully gets unhidden from the list.
    // The current user's channel view should be refreshed to reflect the change.
    ...
})
ArgumentDescription

IS_HIDE_PREVIOUS_MESSAGES

Type: BOOL
When the channel gets appeared back in the list, determines whether to conceal the messages sent and received before hiding or archiving the channel. If set to YES, the previous messages aren't displayed in the channel. (Default: NO)

IS_ALLOW_AUTO_UNHIDE

Type: BOOL
Determines the state and operating behavior of the channel in the list. If set to YES, the channel is hidden from the list, automatically gets unhidden when receiving a new message from other members, and appears back. If set to NO, the channel is archived and disappeared from the list, and never appears back unless the unhideChannelWithCompletionHandler: is called for unarchiving. (Default: YES)

Using the channel.hiddenState, you can check the channel state with regard to the list.

Objective-C
Swift
Light Color Skin
Copy
if (channel.hiddenState == SBDGroupChannelHiddenStateUnhidden) {
    // Display the channel in the list.
} else if (channel.hiddenState == SBDGroupChannelHiddenStateHiddenAllowAutoUnhide) {
    // Hide the channel from the list, and get it appeared back on condition.
} else if (channel.hiddenState == SBDGroupChannelHiddenStateHiddenPreventAutoUnhide) {
    // Archive the channel, and get it appeared back in the list only when the unhideChannelWithCompletionHandler: is called.
}
Light Color Skin
Copy
if channel.hiddenState == SBDChannelHiddenStateFilter.hiddenStateUnhidden {
    // Display the channel in the list.
} else if channel.hiddenState == SBDChannelHiddenStateFilter.hiddenAllowAutoUnhide {
    // Hide the channel from the list, and get it appeared back on condition.
} else if channel.hiddenState == SBDChannelHiddenStateFilter.hiddenPreventAutoUnhide {
    // Archive the channel, and get it appeared back in the list only when the unhideChannel() is called.
}

You can also filter channels by their state like the following:

Objective-C
Swift
Light Color Skin
Copy
SBDGroupChannelListQuery *listQuery = [SBDGroupChannel createMyGroupChannelListQuery];
// The filter options are limited to 'SBDGroupChannelHiddenStateFilterUnhiddenOnly', 'SBDGroupChannelHiddenStateFilterHiddenOnly', 'SBDGroupChannelHiddenStateFilterHiddenAllowAutoUnhide', or 'SBDGroupChannelHiddenStateFilterHiddenPreventAutoUnhide'.
// If set to 'SBDGroupChannelHiddenStateFilterHiddenOnly', hidden and archived channels are returned.
listQuery.channelHiddenStateFilter = SBDGroupChannelHiddenStateFilterHiddenPreventAutoUnhide;

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

    // Only archived channels are returned in a result list through the "groupChannels" parameter of the callback method.
    ...
}];
Light Color Skin
Copy
let listQuery = SBDGroupChannel.createMyGroupChannelListQuery()
// The filter options are limited to 'SBDChannelHiddenStateFilter.unhiddenOnly', 'SBDChannelHiddenStateFilter.hiddenOnly', 'SBDChannelHiddenStateFilter.hiddenAllowAutoUnhide', or 'SBDChannelHiddenStateFilter.hiddenPreventAutoUnhide'.
// If set to 'SBDChannelHiddenStateFilter.hiddenOnly', hidden and archived channels are returned.
listQuery?.channelHiddenStateFilter = SBDChannelHiddenStateFilter.hiddenPreventAutoUnhide

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

    // Only archived channels are returned in a result list through the "groupChannels" parameter of the callback method.
    ...
})

Filter channels by user IDs

Using the SBDGroupChannelListQuery's userIdsExactFilter or userIdsIncludeFilter, you can filter group channels by user IDs. Let's assume the ID of the current user is Harry and the user is a member of two group channels:

  • channelA consists of Harry, John, and Jay.
  • channelB consists of Harry, John, Jay, and Jin.

A userIdsExactFilter returns a list of the current user's group channels containing exactly the queried user IDs. In case you specify only one user ID in the filter, the filter returns a list of the current user's one (distinct) or more 1-on-1 group channels with the specified user.

Objective-C
Swift
Light Color Skin
Copy
SBDGroupChannelListQuery *listQuery = [SBDGroupChannel createMyGroupChannelListQuery];
[listQuery setUserIdsExactFilter:@[@"John", @"Jay"]];
[listQuery loadNextPageWithCompletionHandler:^(NSArray<SBDGroupChannel *> * _Nullable groupChannels, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // Only channelA is returned in a result list through the "list" parameter of the callback method.
    ...
}];
Light Color Skin
Copy
let listQuery = SBDGroupChannel.createMyGroupChannelListQuery()
listQuery?.userIdsExactFilter = ["John", "Jay"]
listQuery?.loadNextPage(completionHandler: { (groupChannels, error) in
    guard error == nil else {
        // Handle error.
    }

    // Only channelA is returned in a result list through the "list" parameter of the callback method.
    ...
})

A userIdsIncludeFilter returns a list of the current user's group channels including the queried user IDs partially and exactly. Two different results can be returned according to the value of the queryType parameter.

Objective-C
Swift
Light Color Skin
Copy
SBDGroupChannelListQuery *listQuery = [SBDGroupChannel createMyGroupChannelListQuery];
[listQuery setUserIdsIncludeFilter:@[@"John", @"Jay", @"Jin"] queryType:SBDGroupChannelListQueryTypeAnd];
[listQuery loadNextPageWithCompletionHandler:^(NSArray<SBDGroupChannel *> * _Nullable groupChannels, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // Only channelB including {'John', 'Jay', 'Jin'} as a subset is returned in a result list.
    ...
}];

[listQuery setUserIdsIncludeFilter:@[@"John", @"Jay", @"Jin"] queryType:SBDGroupChannelListQueryTypeOr];
[listQuery loadNextPageWithCompletionHandler:^(NSArray<SBDGroupChannel *> * _Nullable groupChannels, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // channelA and channelB including {'John'}, channelA and channelB including {'Jay'}, channelB that including {'Jin'}.
    // Actually, channelA and channelB are returned in a result list.
    ...
}];
Light Color Skin
Copy
let listQuery = SBDGroupChannel.createMyGroupChannelListQuery()
listQuery?.setUserIdsIncludeFilter(["John", "Jay", "Jin"], queryType: SBDGroupChannelListQueryType.and)
listQuery?.loadNextPage(completionHandler: { (groupChannels, error) in
    guard error == nil else {
        // Handle error.
    }

    // channelA and channelB including {'John'}, channelA and channelB including {'Jay'}, channelB that including {'Jin'}.
    // Actually, channelA and channelB are returned in a result list.
    ...
})

listQuery?.setUserIdsIncludeFilter(["John", "Jay", "Jin"], queryType: SBDGroupChannelListQueryType.or)
listQuery?.loadNextPage(completionHandler: { (groupChannels, error) in
    guard error == nil else {
        // Handle error.
    }

    // channelA and channelB that include {'John'}, plus channelA and channelB that include {'Jay'}, plus channelB that includes {'Jin'}.
    // Actually channelA and channelB are returned.
})

Send a message

In a group channel, users 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];

[groupChannel 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 userMesage.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

groupChannel.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 userMesage.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.
    long long messageId = fileMessage.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<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 setMentionType:SBDMentionTypeUsers];            // Either SBDMentionTypeUsers or SBDMentionTypeChannel
[params setMentionedUserIds:@[@"Jeff", @"Julia"]];    // or setMentionedUsers:LIST_OF_USERS_TO_MENTION
[params setPushNotificationDeliveryOption:SBDPushNotificationDeliveryOptionDefault];

[groupChannel 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 fileMesage.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.
    ...
}];
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

groupChannel.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 fileMesage.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.
    ...
})

If an app goes to the background while uploading a file such as a profile image or a picture, the app can complete the uploading process by using application:handleEventsForBackgroundURLSession:completionHandler: method in your AppDelegate. To complete the uploading, a background event delegate should be added and implemented in the following delegation. If you don't want to upload the 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

Users can send critical alert messages 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.

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;
[groupChannel 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;
[groupChannel 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
groupChannel.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
groupChannel.sendFileMessage(with: fileMessageParams!) { (fileMessage, error) in
    if error != nil {
        // Handle error.
    }
}

Receive messages through a channel delegate

Messages sent from other members can be received through the channel:didReceiveMessage: method in the channel delegate. A SBDBaseMessage object for each received message is one of the following three 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 Platform API

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

Objective-C
Swift
Light Color Skin
Copy
@interface GroupChannelChattingViewController : UIViewController<SBDChannelDelegate>

@end

@implementation GroupChannelChattingViewController

- (void)initGroupChannelChattingViewController {
    [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 GroupChannelChattingViewController: 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.
[groupChannel 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.
groupChannel?.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.
    ...
})
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;
...

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

// Pass the params to the parameter in the `sendFileMessageWithParams:completionHandler:` method.
groupChannel?.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.
    ...
})
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 members in a message

When a member wants to call the attention of other members of a group channel, they can mention those members 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 members 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];

[groupChannel 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
}

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

    ...
})

React to a message

Message reactions will help you build a more engaging chat experience that goes beyond text messages. They are a quick and easy way for users to respond to a message. Users can express their acknowledgement of or feelings about a message without written text by simply adding reactions. They can also view and delete their reactions to the message.

Note: Currently, message reactions are only available in group channels.

Objective-C
Swift
Light Color Skin
Copy
NSString *emojiKey = @"smile";
// The BASE_MESSAGE below indicates an SBDBaseMessage object to add a reaction to.
[groupChannel addReactionWithMessage:BASE_MESSAGE key:emojiKey completionHandler:^(SBDReactionEvent * _Nullable reactionEvent, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];

// The BASE_MESSAGE below indicates an SBDBaseMessage object to delete a reaction from.
[groupChannel deleteReactionWithMessage:BASE_MESSAGE key:emojiKey completionHandler:^(SBDReactionEvent * _Nullable reactionEvent, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];

// Note: To add or remove the emoji of which key matches 'smile' below the message on the current user's chat view,
// the applyReactionEvent: method should be called in the channel event delegate's channel:updatedReaction: method.
Light Color Skin
Copy
let emojiKey = "smile"
// The BASE_MESSAGE below indicates an SBDBaseMessage object to add a reaction to.
groupChannel.addReaction(with: BASE_MESSAGE, key: emojiKey, completionHandler: { (reactionEvent, error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

// The BASE_MESSAGE below indicates an SBDBaseMessage object to delete a reaction from.
groupChannel.deleteReaction(with: BASE_MESSAGE, key: emojiKey, completionHandler: { (reactionEvent, error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

// Note: To add or remove the emoji of which key matches 'smile' below the message on the current user's chat view,
// the apply() method should be called in the channel event delegate's updatedReaction() method.

You can decide how to display reactions that were added to messages in the current user’s chat view.

Objective-C
Swift
Light Color Skin
Copy
[groupChannel getPreviousMessagesByTimestamp:TIMESTAMP ... includeReactions:INCLUDE_REACTIONS completionHandler:^(NSArray<SBDBaseMessage *> * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    for (SBDBaseMessage *message in messages) {
        ...

        for (SBDReaction *reaction in [message getReactions]) {
            // Check if this emoji has been used when the current user reacted to the message.
            if ([[reaction getUserIds] indexOfObject:[SBDMain getCurrentUser].userId] != NSNotFound) {
                NSString *key = reaction.key;
                NSNumber *updatedAt = reaction.updatedAt;

                // Show the emoji however you want on the current user's chat view.
            }
        }
    }
}];
Light Color Skin
Copy
groupChannel.getPreviousMessages(byTimestamp: TIMESTAMP, ..., includeReactions: INCLUDE_REACTIONS, completionHandler: { (messages, error) in
    guard error == nil else {
        // Handle error.
    }

    for message in messages! {
        ...

        for reaction in message.reactions {
            // Check if this emoji has been used when the current user reacted to the message.
            if reaction.userIds.firstIndex(of: SBDMain.getCurrentUser()!.userId) != nil {
                let key = reaction.key
                let updatedAt = reaction.updatedAt

                // Show the emoji however you want on the current user's chat view.
            }
        }
    }
})

Note: By using the SBDPreviousMessageListQuery's loadPreviousMessagesWithLimit:reverse:completionHandler: method, messages along with their reactions can also be retrieved. To learn more, refer to the Load previous messages section below.

If one of the channel members reacts to a message, the channel:updatedReaction: method in the channel event delegate will be invoked on all channel members’ devices including the one that belongs to the current user. The applyReactionEvent: method will reflect the reaction change to the message in real time.

Objective-C
Swift
Light Color Skin
Copy
- (void)channel:(SBDBaseChannel *)sender updatedReaction:(SBDReactionEvent *)reactionEvent {
    ...

    // If there is a message with the reactionEvent.messageId,
    // you can apply the reaction change to the message by calling the applyReactionEvent: method.
    [message applyReactionEvent:reactionEvent];

    // Add or remove an emoji below the message on the current user's chat view.
}
Light Color Skin
Copy
func channel(_ sender: SBDBaseChannel, updatedReaction reactionEvent: SBDReactionEvent) {
    ...

    // If there is a message with the reactionEvent.messageId,
    // you can apply the reaction change to the message by calling the apply() method.
    message.apply(reactionEvent)

    // Add or remove an emoji below the message on the current user's chat view.
}

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 a group channel. With a returned list, you can display the past messages in your UI once they have loaded.

Note: You can decide whether a user can see the messages sent prior to the user joining a group channel. In your dashboard, go to the Settings > Chat > Channels > Group channels, there is the Chat history option. If turned on, new users are allowed to view a message history in joined group channels. If turned off, new users aren't allowed to see the messages prior to joining a group channel.

Objective-C
Swift
Light Color Skin
Copy
// There should only be one single instance per channel view.
SBDPreviousMessageListQuery *listQuery = [groupChannel createPreviousMessageListQuery];
listQuery.includeMetaArray = YES;   // Retrieve a list of messages along with their metaarrays.
listQuery.includeReactions = YES;   // Retrieve a list of messages along with their reactions.
...

// Retrieving previous messages.
[listQuery loadPreviousMessagesWithLimit:LIMIT reverse:REVERSE completionHandler:^(NSArray<SBDBaseMessage *> * _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 = groupChannel.createPreviousMessageListQuery()
listQuery?.includeMetaArray = true  // Retrieve a list of messages along with their metaarrays.
listQuery?.includeReactions = true  // Retrieve a list of messages along with their reactions.
...

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

    ...
})
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 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 loadPreviousMessagesWithLimit:reverse:completionHandler: method again, you should receive a success callback through the completionHandler first.

The following table shows all the supported filters for SBDPreviousMessageListQuery to search for messages you want to retrieve. You can use any filters in a similar fashion with the sample code above.

NameFilters...

MessageTypeFilter

Messages with the specified message type. Specifying the messageTypeFilter option with a custom message type enables this filter.

CustomTypeFilter

Messages with the specified custom message type. Specifying the customTypeFilter option with a custom message type enables this filter.

S1enderUserIdsFilter

Messages that are sent by the specified users. Specifying the senderUserIdsFilter option with an array of user IDs enables this filter.


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 a group channel.

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];
...

[groupChannel getMessagesByTimestamp:TIMESTAMP params:params completionHandler:^(NSArray<SBDBaseMessage *> * _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
...

groupChannel.getPreviousMessages(byTimestamp: 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!
    ...
})
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 a group 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];
...

[groupChannel getMessagesByMessageId:MESSAGE_ID params: params completionHandler:^(NSArray<SBDBaseMessage *> * _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
...

groupChannel.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!
    ...
})
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 = [groupChannel 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<SBDBaseMessage *> * _Nullable messages, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
let listQuery = groupChannel!.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.
    }

    ...
})
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
PropertyDescription

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
[groupChannel getMessagesByTimestamp:TIMESTAMP params:params completionHandler:^(NSArray<SBDBaseMessage *> * _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
groupChannel?.getMessagesByTimestamp(TIMESTAMP, params: params, completionHandler: { (messages, error) in
    if error != nil {
        // Handle error.
    }

    // A list of previous aƒrepnd 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!
    ...
})
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
[groupChannel getMessagesByMessageId:MESSAGE_ID params:params completionHandler:^(NSArray<SBDBaseMessage *> * _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
groupChannel?.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!
    ...
})
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<SBDBaseMessage *> * _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.
    ...
}
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.
    ...
}
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: NSInteger
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 a 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.
[groupChannel 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.
[groupChannel 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.
groupChannel.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.
groupChannel.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 GroupChanneChattinglViewController : UIViewController<SBDChannelDelegate>

@end

@implementation GroupChannelChattingViewController

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

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

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

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

Delete a message

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

Objective-C
Swift
Light Color Skin
Copy
// The BASE_MESSAGE below indicates a BaseMessage object to delete.
[groupChannel 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.
groupChannel.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 GroupChannelChattingViewController : UIViewController<SBDChannelDelegate>

@end

@implementation GroupChannelChattingViewController

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

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

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

    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
[groupChannel 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
groupChannel.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
[groupChannel 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
groupChannel.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.
    ...
})
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.


Clear the chat history

By using the resetMyHistoryWithCompletionHandler: method, you can help the current user clear the chat history in a group channel and start a fresh conversation with other members in the same channel. As the method's name implies, the chat history will be cleared only from the channel view of the current user, and will no longer be shown in that view. But the messages are not deleted from the database of the Sendbird system, and other members can still see all the messages in their channel views.

This method simply clears the messages for the user by updating the lastMessage and readReceipts properties of a group channel object in addition to other internally managed data such as the number of the user’s unread message.

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

    ...
}];
Light Color Skin
Copy
groupChannel.resetMyHistory(completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

When a user is online, all data associated with the group channels they are a member of are automatically updated by the SBDMain instance. However, when a user is disconnected from Sendbird server and reconnects later, you should call the refreshWithCompletionHandler: method to update the channels with the latest information.

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

    ...
}];
Light Color Skin
Copy
groupChannel.refresh(completionHandler: { (error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

Note: If you want to make your users see the channels updated to the most recent when their client apps are in the foreground, we recommend you call the refreshWithCompletionHandler: in the didSucceedReconnection method which receives a callback from Sendbird server when successfully reconnected.


Retrieve a list of all members

You can retrieve a list of members in a group channel using the members property of a SBDGroupChannel object.

Objective-C
Swift
Light Color Skin
Copy
NSArray<SBDMember *> *members = [groupChannel members];
Light Color Skin
Copy
let members = groupChannel?.members

Members of a group channel are automatically updated when a user is online. But when a user is disconnected from Sendbird server and then reconnected, you should use the refreshWithCompletionHandler: method to update their channels with the latest information. See the Refresh all data related to a group channel section for the sample code.


Retrieve the online status of members

To stay updated on the online status of each member in a group channel, call the refreshWithCompletionHandler: method before using the members property of a SBDGroupChannel object to retrieve the members of the channel.

By checking the connectionStatus property of each SBDMember object in the members property, you can then retrieve the user's current connection status. The connectionStatus property 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 your client app needs to keep track of the connection status of 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 members and operators in a specific order

The members and operators of a group channel can be retrieved by using the loadNextPageWithCompletionHandler: method of a SBDGroupChannelMemberListQuery instance. For a specific order, set either option in the table below to the order property of SBDGroupChannelMemberListQuery.

- SBDMemberListOrder

ValueDescription

SBDMemberListOrderNicknameAlphabetical

Members are arranged in an alphabetical order (Default).

SBDMemberListOrderOperatorThenMemberNicknameAlphabetical

Operators are sequenced before the members, both in an alphabetical order.

Objective-C
Swift
Light Color Skin
Copy
SBDGroupChannelMemberListQuery *listQuery = [groupChannel createMemberListQuery];
listQuery.limit(10);
listQuery.order = SBDMemberListOrderOperatorThenMemberNicknameAlphabetical;

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

    // A list of matching members and operators is successfully retrieved.
    // Through the "users" parameter of the callback method,
    // you can access the data of each item from the result list that Sendbird server has passed to the callback method.
    for (SBDMember *user in users) {
        ...
    }
}];
Light Color Skin
Copy
let listQuery = groupChannel.createOperatorListQuery()
listQuery?.limit = 10   // In an alphabetical order by default
listQuery?.order = SBDMemberListOrderOperatorThenMemberNicknameAlphabetical

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

    // A list of matching members and operators is successfully retrieved.
    // Through the "users" parameter of the callback method,
    // you can access the data of each item from the result list that Sendbird server has passed to the callback method.
    for user in users! {
        ...
    }
})

- SBDGroupChannelOperatorFilter

For filtering, set one of the options in the table below to the operatorFilter of SBDGroupChannelMemberListQuery.

ValueDescription

SBDGroupChannelOperatorFilterAll

No filter is applied to the group channel list (Default).

SBDGroupChannelOperatorFilterOperator

Only operators are retrieved for the list.

SBDGroupChannelOperatorFilterNonOperator

All members, except for operators, are retrieved for the list.

Objective-C
Swift
Light Color Skin
Copy
SBDGroupChannelMemberListQuery *listQuery = [groupChannel createMemberListQuery];
listQuery.limit(10);
listQuery.operatorFilter = SBDGroupChannelOperatorFilterOperator;  // In an alphabetical order by default

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

    // A list of matching members and operators is successfully retrieved.
    // Through the "users" parameter of the callback method,
    // you can access the data of each item from the result list that Sendbird server has passed to the callback method.
    for (SBDMember *user in users) {
        ...
    }
}];
Light Color Skin
Copy
let listQuery = groupChannel.createMemberListQuery()
listQuery?.limit = 10
listQuery.operatorFilter = SBDGroupChannelOperatorFilterOperator  // In an alphabetical order by default

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

    // A list of matching members and operators is successfully retrieved.
    // Through the "users" parameter of the callback method,
    // you can access the data of each item from the result list that Sendbird server has passed to the callback method.
    for user in users! {
        ...
    }
})

Retrieve a list of operators

You can create a SBDOperatorListQuery instance and use the loadNextPageWithCompletionHandler: method to retrieve a list of operators who monitor and control the activities in a group channel.

Objective-C
Swift
Light Color Skin
Copy
SBDOperatorListQuery *listQuery = [groupChannel createOperatorListQuery];
[listQuery loadNextPageWithCompletionHandler:^(NSArray<SBDUser *> * _Nullable users, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    // Retrieving operators.
    for (SBDUser *operator in users) {
        ...
    }
}];
Light Color Skin
Copy
let listQuery = groupChannel.createOperatorListQuery()
listQuery?.loadNextPage(completionHandler: { (users, error) in
    guard error == nil else {
        // Handle error.
    }

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

Register operators

You can register members as an operator of a group channel.

Objective-C
Swift
Light Color Skin
Copy
[groupChannel 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
groupChannel.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 a group channel but leave them as members.

Objective-C
Swift
Light Color Skin
Copy
[groupChannel 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
groupChannel.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
[groupChannel removeAllOperatorsWithCompletionHandler:^(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
groupChannel.removeAllOperators { (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.
    ...
}

Retrieve a list of banned or muted users

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

Objective-C
Swift
Light Color Skin
Copy
// Retrieving banned users.
SBDBannedUserListQuery *listQuery = [groupChannel createBannedUserListQuery];
[listQuery loadNextPageWithCompletionHandler:^(NSArray<SBDUser *> * _Nullable users, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];

// Retrieving muted users.
SBDGroupChannelMemberListQuery *listQuery = [groupChannel createMemberListQuery];
[listQuery setMutedMemberFilter:SBDGroupChannelMutedMemberFilterMuted];
[listQuery loadNextPageWithCompletionHandler:^(NSArray<SBDMember *> * _Nullable users, SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];
Light Color Skin
Copy
// Retrieving banned users.
let listQuery = groupChannel.createBannedUserListQuery()
listQuery?.loadNextPage(completionHandler: { (users, error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

// Retrieving muted users.
let listQuery = groupChannel.createMemberListQuery()
listQuery?.mutedMemberFilter = SBDGroupChannelMutedMemberFilter.muted
listQuery?.loadNextPage(completionHandler: { (members, error) in
    guard error == nil else {
        // Handle error.
    }

    ...
})

Ban and unban a user

Operators of a group 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 join the channel again after the time period set by the operators. The operators can ban and unban users from group channels using the following code.

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

    if (groupChannel.myRole == SBDRoleOperator) {
        [groupChannel banUser:USER seconds:SECONDS description:DESCRIPTION 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.
            ...
        }];

        [groupChannel 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
SBDGroupChannel.getWithUrl(CHANNEL_URL, completionHandler: { (groupChannel, error) in
    guard error == nil else {
        // Handle error.
    }

    if groupChannel?.myRole == SBDRole.operator {
        groupChannel?.ban(USER, seconds: SECONDS, description: DESCRIPTION, 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.
            ...
        })

        groupChannel?.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 abilities.


Mute and unmute a user

Operators of a group channel can prohibit the 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 the channel using the following code:

Objective-C
Swift
Light Color Skin
Copy
[SBDGroupChannel getChannelWithUrl:CHANNEL_URL completionHandler:^(SBDGroupChannel * _Nullable groupChannel, SBDError * _Nullable error) {
    if (groupChannel.myRole == SBDRoleOperator) {
        [groupChannel 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.
            ...
        }];

        [groupChannel 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
SBDGroupChannel.getWithUrl(CHANNEL_URL, completionHandler: { (groupChannel, error) in
    if groupChannel?.myRole == SBDRole.operator {
        groupChannel?.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.
            ...
        })

        groupChannel?.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 abilities.


Report a message, a user, or a channel

In a group 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.
[groupChannel reportMessage:MESSAGE_TO_REPORT reportCategory:REPORT_CATEGORY reportDescription:DESCRIPTION completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) {
        // Handle error.
    }

    ...
}];

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

    ...
}];

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

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

    ...
})

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

    ...
})

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

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