Pinning Channels

Channel members can pin a channel for themselves. This is a per-user setting that does not affect other members.

Pinned channels function identically to regular channels via the API, but your UI can display them separately. When a channel is pinned, the timestamp is recorded and returned as pinned_at in the response.

When querying channels, filter by pinned: true to retrieve only pinned channels, or pinned: false to exclude them. You can also sort by pinned_at to display pinned channels first.

Pin a Channel

// Controllers

// Pin the channel for the current user.
channelController.pin { error in
    if let error {
        // handle error
    }
}

// Query all the pinned channels.
let channelListController = chatClient.channelListController(
    query: ChannelListQuery(
        filter: .and([
            .containMembers(userIds: [currentUserId]),
            .equal(.pinned, to: true)
        ])
    )
)
channelListController.synchronize { error in
    if let error {
        // handle error
    } else {
        let pinnedChannels = channelListController.channels
    }
}

// Unpin the channel for the current user.
channelController.unpin { error in
    if let error {
        // handle error
    }
}

// State layer (async-await)

// Pin the channel for the current user
try await chat.pin()

// Query all the pinned channels.
let channelList = chatClient.makeChannelList(
    with: ChannelListQuery(
        filter: .and([
            .containMembers(userIds: [currentUserId]),
            .equal(.pinned, to: true)
        ])
    )
)
try await channelList.get()
let pinnedChannels = channelList.state.channels

// Unpin the channel for the current user.
try await chat.unpin()

Global Pinning

Channels are pinned for a specific member. If the channel should instead be pinned for all users, this can be stored as custom data in the channel itself. The value cannot collide with existing fields, so use a value such as globally_pinned: true.