Chat UIKit SwiftUI v3
Chat UIKit SwiftUI
Chat UIKit
SwiftUI
Version 3

Chat in a group channel

Copy link

In a group channel, you can have both 1-to-1 chat and 1-to-N chats through the GroupChannelView struct. There are two types of group channel based on whether a user needs an invitation to join: private and public. SwiftUI also provides a Supergroup channel to facilitate a more stable chat environment for a larger number of users.

SwiftUI supports plain text messages, file messages, and media content such as photos and videos to be sent in group channels. Once delivered, those messages are grouped by time in minutes and date in the channel.

To learn more about the channels, go to the Channel types page in Chat SDK.


Features

Copy link

Refer to the table below to see what features there are in GroupChannelView.

FeatureDescription

Send message

Allows users to send messages, images, videos, and files in the message input view.

Notify new messages

Displays a push notification when receiving a new message.

Show last seen time

Shows the timestamp of when a member read the last message in the channel. This function is only available in 1-to-1 chat channels.

Show message send status

Displays the send status of a message as either successful, failed, or sending.

Show delivery receipt

Displays the delivery receipt status of a message in the channel.

Show read receipt

Displays the read receipt status of a message in the channel.

Show typing indicator

Displays whether another user in the channel is typing a message.

Copy message

Allows users to copy a text message.

Edit message

Allows users to edit their own messages.

Delete message

Allows users to delete their own messages.

Retry to send a message

Allows users to try to resend a failed message.

Mention a user in a message

Allows users to mention channel members in a message.

Channel settings menu

Navigates to the group channel settings view from the navigation bar.

Go back to previous view

Returns the user to the previous view from the navigation bar.

Show channel status banner

Displays the channel status in the top banner of the view. By default, the banner only shows the frozen state of the channel.


Initialize

Copy link

You can start building a channel-based chat service by calling the GroupChannelView structure. It's also in charge of auto connecting to Sendbird server and internal functions to handle core features of SwiftUI such as pagination and real-time updates.

Note: You can initialize GroupChannelView by setting the value of GroupChannelViewProvider with channelURL. If you've already created MessageListParams, we recommend you to set all of the objects together. Otherwise, the default values are used for these structure.

You can start building a chat in group channel view through the GroupChannelView structure. Use the init(provider:) initializer to create the instance and display the view.

GroupChannelViewProvider is a class that provides the necessary data for the GroupChannelView to render the view. It has various data properties such as channelURL, startingPoint, and messageListParams. A GroupChannelViewProvider instance is required to initialize the GroupChannelView.

import SwiftUI
import SendbirdSwiftUI

struct ContentView: View {
    @ObservedObject var provider: GroupChannelViewProvider

    var body: some View {
        GroupChannelView(provider: provider)
    }
}

Init parameters

Copy link
ParameterTypeRequired

provider

GroupChannelViewProvider

o

GroupChannelViewProvider init parameters

Copy link
ParameterTypeRequired

channelURL

String

o

startingPoint

Int64

x

messageListParams

MessageListParams

x


Accessing data and methods

Copy link

GroupChannelViewProvider provides various data and methods related to the GroupChannelView that you can use to customize the view. The below are @Published properties that you can access from the GroupChannelViewProvider.

ParameterTypeDescription

channels

[GroupChannel]

A list of group channels.

isLoading

Bool

Indicates whether the list is loading or not

MethodDescription

showCreateChannel()

presents CreateChannelView

showCreateChannelTypeSelector()

presents a view that lets you select which group channel type to create

The below is an example of using the GroupChannelViewProvider data and methods.

import SwiftUI
import SendbirdSwiftUI

struct ContentView: View {
    @ObservedObject var provider: GroupChannelViewProvider
    
    var body: some View {
        GroupChannelView(
            provider: provider,
            headerItem: {
                .init()
                .titleLabel { _ in
                    Text("\(provider.fullMessages.count) messages")
                        .padding()
                        .background(Color.blue)
                }
            }
        )
    }
}

Customization

Copy link

Sendbird Chat SwiftUI provides a View customization and DestinationViewBuilder.

  • View customization: Our SwiftUI SDK allows you to selectively customize view elements. To learn more about the customization and our SwiftUI is designed, see the customization guide.
  • DestinationViewBuilder: Use DestinationViewBuilder to customize the destination views that are navigatable from the group channel view.

You can use data and methods from the View Provider when customize the View.

Note : Visit our Github Sample to see the custom sample implementation for each item.

Partial customization

Copy link

You can easily customize a specific part of a View, which particularly comes in handy when changing only a certain area in the View. To do so, use the View Builders that Sendbird has predefined and its a ViewConfig. The ViewConfig contains the data needed to render the view and its parameters can be found in the table below.

Parameter

Copy link
ParameterTypeView builders

headerItem

() -> GroupChannelType.HeaderItem

leftView
rightView
titleView
- coverImage
- titleLabel
- typingStatusView

listItem

() -> GroupChannelType.ListItem

rowView
senderProfileImage
userMessageView
fileMessageView
multipleFilesMessageView
adminMessageView
typingIndicatorView
newMessageInfoView
scrollBottomView
channelStateBanner

inputItem

() -> GroupChannelType.InputItem

leftView
- addButton
rightView
- sendButton
- voiceButton

The following code demonstrates how to replace the view items using headerItem. All other {Component}Items can be used in the same way.

Note : When you customize a parent view, customizations in the child views will not be applied. For example, if you customize the titleView in the headerItem, the customizations of the coverImage or titleLabel in the lower view items will not be applied.

GroupChannelView(
    provider: provider,
    headerItem: {
        .init()
        .leftView { viewConfig in
            Text("Left")
        }
        .rightView { viewConfig in // Use chaining.
            Text("Right")
        }
    }
)

Full customization

Copy link

At this moment, this screen does not support entire customization.

DestinationViewBuilder

Copy link

Sendbird Chat SwiftUI is designed to internally navigate from each view to its connected view. However, if you need to customize the destination view, you can do so by using the interface provided by the DestinationViewBuilder.

DestinationViewBuilder method

Copy link
MethodViewBuilder type

channelSettingsView

GroupChannelSettingsViewBuilder

messageThreadView

MessageThreadViewBuilder

The following code demonstrates how to replace the channel settings view connected from the channel view.

GroupChannelView(provider: provider)
    .channelSettingsView { channelURL in
        GroupChannelSettingsView(channelURL: channelURL)
    }

Note : If you've customized a child view of another view, you need to set the destination view for all the views from the top to the destination view.


Message menu

Copy link

A long tap on a message object in the chat view will display a list of actions that can be performed on the message.

The code snippets below demonstrate how to customize the menu items.

import SwiftUI
import SendbirdSwiftUI
import SendbirdChatSDK

struct ContentView: View {
    @ObservedObject var provider: GroupChannelViewProvider = GroupChannelViewProvider(channelURL: "CHANNEL_URL")
    
    var body: some View {
        GroupChannelView(provider: provider,
                         listItem: {
            .init()
            .rowView(content: {viewConfig in VStack(alignment: .leading) {
                Button(action: {
                    openChat(message: viewConfig.message)
                }) {
                    Text(viewConfig.message.message)
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                }
                
            }})
        }
        )
    }
    
    func openChat(message: SendbirdChatSDK.BaseMessage) {
        // Define your custom menu items
        let menuItems: [SBUMenuItem] = [
            SBUMenuItem(
                title: "Delete",
                image: UIImage(systemName: "trash"),
                completionHandler: { /* handle delete action */ }),
            SBUMenuItem(
                title: "Copy",
                image: UIImage(systemName: "doc.on.doc"),
                completionHandler: { /* handle copy action */ }),
            SBUMenuItem(
                title: "Reply",
                image: UIImage(systemName: "arrowshape.turn.up.left"),
                completionHandler: { /* handle reply action */ })
        ]
        let menuSheetVC = SBUMenuSheetViewController.init(message: message, items: menuItems, useReaction: true)
        if #available(iOS 15.0, *) {
            // For iOS 15+, use sheetPresentationController to set the detents (height of the sheet)
            menuSheetVC.sheetPresentationController?.detents = [
                .medium() // Set the height to medium (you can adjust this as needed)
            ]
            menuSheetVC.sheetPresentationController?.prefersGrabberVisible = true // Optional: Add a grabber for interaction
        } else {
            // For older iOS versions, use .pageSheet for a smaller bottom sheet
            menuSheetVC.modalPresentationStyle = .pageSheet
        }
        
        // Present the menu sheet from the cell's view controller
        if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
           let rootViewController = windowScene.windows.first?.rootViewController {
            rootViewController.present(menuSheetVC, animated: true, completion: nil)
        }
    }
}

Message order

Copy link

In the channel, message list are organized based on their sending status and their arrival time.

In this layout, older messages are positioned at the top of the list, while the most recent messages appear at the bottom. As new messages are successfully sent and received, they are displayed at the lower end of the list, just above any messages that are pending or have failed. Below these, you'll find any messages that are still pending or have failed to send. These are ordered based on their original sending time. Furthermore, if the bubble typing indicator feature is enabled for your channel, this indicator will be consistently shown at the very bottom of the message list, regardless of the statuses of other messages. This layout prioritizes the visibility of new, successful messages while maintaining awareness of pending and failed messages, as well as ongoing typing activity.