Channel Controllers

ChannelListController

ChatChannelListController allows you to observe a list of chat channels based on the provided query and to paginate channels.

Publishers in ChannelListController

To receive a queried list of channels, you can use the channelsChangesPublisher provided by the ChatChannelListController

 channelListController
            .channelsChangesPublisher
            .sink(receiveValue: { 
                // process the channel changes here
            })
            .store(in: &cancellables)

ChannelController

ChatChannelController allows you to observe and mutate data for one channel.

Publishers in ChannelController

The channelChangePublisher will emit a new value every time the channel changes.

channelController
            .channelChangePublisher
            .sink(receiveValue: { 
                // Process the updated channel data here
            })
            .store(in: &cancellables)

The messagesChangesPublisher will emit a new value every time the list of the messages matching the query changes.

channelController
            .messagesChangesPublisher
            .sink(receiveValue: { 
                //Process the messages changes here 
            })
            .store(in: &cancellables)

The memberEventPublisher will emit a new value every time a member event is received.

channelController
            .memberEventPublisher
            .sink(receiveValue: { 
                // Process the member events here
            })
            .store(in: &cancellables)

The typingUsersPublisher will emit a new value every time typing users change.

channelController
            .typingUsersPublisher
            .sink(receiveValue: { 
                // Process the changes related to typing users here
            })
            .store(in: &cancellables)

Example: Typing Indicator

Let’s build a simple UIView that shows which user is currently typing in the channel using the typingUsersPublisher


class TypingIndicatorView: UIView {
    var labelView: UILabel = {
        var label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    override public init(frame: CGRect) {
        super.init(frame: frame)
        
        addSubview(labelView)

        NSLayoutConstraint.activate([
            labelView.topAnchor.constraint(equalTo: topAnchor),
            labelView.bottomAnchor.constraint(equalTo: bottomAnchor),
            labelView.leadingAnchor.constraint(equalTo: leadingAnchor),
            labelView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setTypingUsers(_ typingUsers: Set<ChatUser>) {
        guard let typingUser = typingUsers.first else {
            labelView.text = ""
            return
        }
        
        labelView.text = "\(typingUser.name ?? typingUser.id) is typing ..."
    }
}

class ViewController: UIViewController {
    var controller: ChatChannelController!
    var cancellables: Set<AnyCancellable> = []

    var typingIndicatorView: TypingIndicatorView = {
        var view = TypingIndicatorView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        let cid = ChannelId.init(type:.messaging, id:"the-id-of-the-channel")
        controller = ChatClient.shared.channelController(for: cid)
        controller.synchronize()

        controller.typingUsersPublisher
            .receive(on: RunLoop.main)
            .sink { [weak self] typingUsers in
                let otherUsersTyping = typingUsers.filter({ $0.id != self?.controller.client.currentUserId })
                self?.typingIndicatorView.setTypingUsers(otherUsersTyping)
            }.store(in: &cancellables)
        
        navigationItem.titleView = typingIndicatorView
    }
}

ChatChannelMemberListController

ChatChannelMemberListController allows you to observe and mutate data and observing changes for a list of channel members based on the provided query.

Publishers in MemberListController

The membersChanges publisher will emit a new value whenever the list of channel members based on the provided query changes.

 memberListController
            .membersChangesPublisher
            .sink(receiveValue: { 
                // Use the member list here
             })
            .store(in: &cancellables)

Example: Listing Members

This example uses the membersChangesPublisher to observe the changes to the members on the channel messaging:123

class MembersSearchResultsView: UIView {
    var labelView: UILabel = {
        var label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    override public init(frame: CGRect) {
        super.init(frame: frame)
        
        addSubview(labelView)

        NSLayoutConstraint.activate([
            labelView.topAnchor.constraint(equalTo: topAnchor),
            labelView.bottomAnchor.constraint(equalTo: bottomAnchor),
            labelView.leadingAnchor.constraint(equalTo: leadingAnchor),
            labelView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setMembers(_ members: [ChatChannelMember]) {
        let membersStr = members.map { $0.name ?? $0.id }.joined(separator: ", ")
        labelView.text = membersStr
    }
}

class ViewController: UIViewController {
    var controller: ChatChannelMemberListController!
    var cancellables: Set<AnyCancellable> = []
    
    var membersSearchResultsView: MembersSearchResultsView = {
        var view = MembersSearchResultsView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let cid = ChannelId.init(type:.messaging, id:"123")
        let query = ChannelMemberListQuery.init(cid: cid)
        
        controller = ChatClient.shared.memberListController(query: query)
        
        controller.synchronize {error in
            if error != nil {
                log.assertionFailure(error!)
            }
        }
        
        controller.membersChangesPublisher
            .receive(on: RunLoop.main)
            .sink { [weak self] _ in
                if let updatedMembers = self?.controller.members {
                    self?.membersSearchResultsView.setMembers(Array(updatedMembers))
                }
            }.store(in: &cancellables)
        
        navigationItem.titleView = membersSearchResultsView
    }
}

ChannelMemberController

ChatChannelMemberController allows you to observe and mutate data and observing changes of a specific chat member.

Publishers in ChannelMemberController

The memberChangePublisher emits a new value protocol every time the member changes.

 memberController
            .memberChangePublisher
            .sink(receiveValue: {  
                // Process the member changes here.
            })
            .store(in: &cancellables)
© Getstream.io, Inc. All Rights Reserved.