---
source_url: https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/channels/join
title: Join channels
updated_at: 2026-06-16T12:48:52.432Z
---

> 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


# Join channels

:::note Requires App Context
Enable [App Context](https://youtu.be/9UEoSlngpYI) on your keyset in the [Admin Portal](https://admin.pubnub.com/) to manage memberships.
:::

Creates a channel membership for the current user. The user is recorded as a channel member.

:::note Listening for messages
`join()` no longer returns a message stream or accepts a message callback. To receive messages after joining, call [onMessageReceived()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/channels/watch) or use [channel.stream.messages()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/channels/watch) separately.
:::

## Method signature

`join()` performs these actions:

* Subscribes the user to a channel
* Creates a `MembershipImpl` object for the user-channel relationship

This method takes the following parameters:

```swift
channel.join(
    custom: [String: JSONCodableScalar]? = nil,
    status: String? = nil,
    type: String? = nil
) async throws -> MembershipImpl
```

### Input

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| custom | [String: | Optional | `nil` | Any custom properties or metadata associated with the channel-user membership in the form of a JSON. Values must be scalar only; arrays or objects are not supported. [App Context filtering language](https://www.pubnub.com/docs/general/metadata/filtering) doesn’t support filtering by custom properties. |
| status | String | Optional | `nil` | Tag that categorizes the membership by its state, like `active` or `inactive`. |
| type | String | Optional | `nil` | Tag that categorizes the membership by its function, like `moderator` or `viewer`. |

### Output

| Parameter | Description |
| --- | --- |
| `MembershipImpl`Type: `MembershipImpl` | Returned object containing info on the newly created user-channel membership. |

## 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.
:::

:::note Access membership properties
`join()` returns a `MembershipImpl` object directly. Access membership properties such as `channel.id` directly on the returned value, for example, `joinResult.channel.id`.
:::

Join the `support` channel and mark this membership as `premium` to add information about your support plan.

###### Closure

```swift
// Assumes a "ChannelImpl" reference named "channel"

channel.join(custom: ["support_plan": "premium"]) { result in
  switch result {
  case let .success(membership):
    debugPrint("Joined channel: \(membership.channel.id)")
  case let .failure(error):
    debugPrint("An error occurred: \(error)")
  }
}
// Important: Keep a strong reference to the returned "AutoCloseable" object as long as you want
// to receive new messages. If the "AutoCloseable" is deallocated, the stream will be cancelled,
// and no further items will be produced. You can also stop receiving messages manually
// by calling the "close()" method on the "AutoCloseable" object.
autoCloseable = channel.onMessageReceived { message in
  debugPrint("Received a new message: \(message)")
}
```

###### AsyncStream

```swift
// Assumes a "ChatImpl" reference named "chat"
Task {
  if let channel = try await chat.getChannel(channelId: "support") {
    // Join the channel
    let membership = try await channel.join(custom: ["support_plan": "premium"])
    debugPrint("Joined channel: \(membership.channel.id)")
    // Continuously listen for new messages on the channel
    for await message in channel.stream.messages() {
      debugPrint("Received a new message: \(message)")
    }
  } else {
    debugPrint("Channel not found")
  }
}
```