Updating a Channel

There are two ways to update a channel using the Stream API - a partial or full update. A partial update will retain any custom key-value data, whereas a complete update is going to remove any that are unspecified in the API request.

Partial Update

A partial update can be used to set and unset specific fields when it is necessary to retain additional custom data fields on the object. AKA a patch style update.

channelController.partialChannelUpdate(
    extraData: [
        "source": .string("user"),
        "source_detail": .dictionary(["user_id": .number(123)]),
        "channel_detail": .dictionary([
            "topic": .string("Plants and Animals"),
            "rating": .string("pg")
        ])
    ]
) { error in
    if let error {
        // handle error
    }
}

// let's change the source of this channel
channelController.partialChannelUpdate(unsetProperties: ["source_detail"])

// let's change the source of this channel
channelController.partialChannelUpdate(extraData:["source": "system"])

// since it's system generated we no longer need source_detail
channelController.partialChannelUpdate(unsetProperties: ["source_detail"])

// and finally update one of the nested fields in the channel_detail
channelController.partialChannelUpdate(extraData:["channel_detail.topic": "Nature"])

Full Update (overwrite)

The update function updates all of the channel data. Any data that is present on the channel and not included in a full update will be deleted.

let channelController = chatClient.channelController(for: .init(type: .messaging, id: "general"))

channelController.updateChannel(
    name: "My special channel",
    imageURL: nil,
    team: nil,
    extraData: [
        "name": .string("myspecialchannel"),
        "color": .string("green"),
    ]
) { error in
    if let error {
        // handle error
    }
}

Request Params

NameTypeDescriptionOptional
channel dataobjectObject with the new channel information. One special field is “frozen”. Setting this field to true will freeze the channel. Read more about freezing channels in “Freezing Channels”
textobjectMessage object allowing you to show a system message in the Channel that something changed.Yes

Updating a channel using these methods cannot be used to add or remove members. For this, you must use specific methods for adding/removing members, more information can be found here.

Archiving a channel

A member in a channel can mark the channel as archived. The archival state is stored for this member, so it doesn’t affect anybody else. From an API point of view, an archived channel is the same as another channel, but the user interface may render an archived channel in a different way. When a channel is archived, the current date is recorded and this is returned as archived_at in the response.

When querying channels, the query can specify specify that archived channels should be excluded. The query can also specify only archived channels.

// Controllers

// Archive the channel for the current user.
channelController.archive { error in
    if let error {
        // handle error
    }
}

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

// Unarchive the channel for the current user.
channelController.unarchive { error in
    if let error {
        // handle error
    }
}

// State layer (async-await)

// Archive the channel for the current user.
try await chat.archive()

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

// Unarchive the channel for the current user.
try await chat.unarchive()

Pinning a channel

Pinning works very similar to archiving. A client can mark a channel as pinned, which can be used to render it differently in the UI. When a channel is pinned, the response contains a pinned_at timestamp.

Like archiving, it’s possible to query channels with a specific pinned state. It is also possible to sort channels by pin, such as returning pinned channels first.

// 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.archive()

// 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 archiving or pinning

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

© Getstream.io, Inc. All Rights Reserved.