---
source_url: https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/pinned
title: Pinned messages
updated_at: 2026-06-19T11:35:17.839Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Pinned messages

Pin messages to channels for easy access. Only one message can be pinned per channel at a time.

Use cases:

* Essential announcements and updates
* Action items and reminders
* Polls and persistent questions

:::note Requires App Context and Message Persistence
Enable [App Context](https://youtu.be/9UEoSlngpYI) and [Message Persistence](https://youtu.be/qLMtbINWGig) in the [Admin Portal](https://admin.pubnub.com/).
:::

## Pin

`pin()` and `pinMessage()` attach a message to a channel. Call `pin()` on a message object or `pinMessage()` on a channel object.

Alternatively, you can also use other Chat SDK methods to pin a message in a thread (thread message) to the [thread channel](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/threads#pin-thread-message-to-thread-channel) or the [parent channel](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/threads#pin-thread-message-to-parent-channel).

### Method signature

These methods take the following parameters:

* pin() (on the Message object) 1message.pin() async throws -> ChannelImpl
* pinMessage() (on the Channel object) 1channel.pinMessage(2 message: MessageImpl3) async throws -> ChannelImpl

#### Input

| Parameter | Required in pin() | Required in pinMessage() | Description |
| --- | --- | --- | --- |
| message | MessageImpl | Optional |  | No | Yes | [MessageImpl object](https://www.pubnub.com/docs/chat/swift-chat-sdk/learn/chat-entities/message) that you want to pin to the selected channel. |

#### Output

| Parameter | Description |
| --- | --- |
| `ChannelImpl` | The updated channel metadata. |

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

Pin the last message on the `incident-management` channel.

* pin() // Assumes a "ChatImpl" reference named "chat" Task { if let channel = try await chat.getChannel(channelId: "incident-management") { if let message = try await channel.getHistory(count: 1).messages.first { let pinnedChannel = try await message.pin() debugPrint("A message was pinned to the channel: \(pinnedChannel)") } else { debugPrint("The channel history is empty. No message to pin.") } } else { debugPrint("Channel not found") } }
* pinMessage() // Assumes a "ChatImpl" reference named "chat" Task { if let channel = try await chat.getChannel(channelId: "incident-management") { if let message = try await channel.getHistory(count: 1).messages.first { let pinnedChannel = try await channel.pinMessage(message: message) debugPrint("A message was pinned to the channel: \(pinnedChannel)") } else { debugPrint("The channel history is empty. No message to pin.") } } else { debugPrint("Channel not found") } }

## Get

`getPinnedMessage()` retrieves the currently pinned message.

### Method signature

This method has the following signature:

```swift
channel.getPinnedMessage() async throws -> MessageImpl?
```

#### Input

This method doesn't take any parameters.

#### Output

| Parameter | Description |
| --- | --- |
| `MessageImpl` | Returned [MessageImpl object](https://www.pubnub.com/docs/chat/swift-chat-sdk/learn/chat-entities/message). |

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

Get the message pinned to the `incident-management` channel.

```swift
// Assumes a "ChatImpl" reference named "chat"
Task {
  if let channel = try await chat.getChannel(channelId: "incident-management") {
    if let message = try await channel.getPinnedMessage() {
      print("Pinned message content: \(message.content)")
    } else {
      debugPrint("No pinned message found in the channel.")
    }
  } else {
    debugPrint("Channel not found")
  }
}
```

## Unpin

`unpinMessage()` unpins a message from the channel.

Alternatively, you can also use other Chat SDK methods to unpin a message in a thread (thread message) from the [thread channel](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/threads#unpin-thread-message-from-thread-channel) or the [parent channel](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/threads#unpin-thread-message-from-parent-channel).

### Method signature

This method has the following signature:

```swift
channel.unpinMessage() async throws -> ChannelImpl
```

#### Input

This method doesn't take any parameters.

#### Output

| Parameter | Description |
| --- | --- |
| `ChannelImpl` | The updated channel metadata. |

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

Unpin the message from the `incident-management` channel.

```swift
// Assumes a "ChatImpl" reference named "chat"
Task {
  if let channel = try await chat.getChannel(channelId: "incident-management") {
    let updatedChannel = try await channel.unpinMessage()
    debugPrint("Updated channel object: \(updatedChannel)")
  } else {
    debugPrint("Channel not found")
  }
}
```