---
source_url: https://www.pubnub.com/docs/sdks/swift/api-reference/publish-and-subscribe
title: Publish/Subscribe API for Swift Native SDK
updated_at: 2026-05-29T11:12:24.529Z
sdk_name: PubNub Swift SDK
sdk_version: 10.1.6
---

> 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


# Publish/Subscribe API for Swift Native SDK

PubNub Swift SDK, use the latest version: 10.1.6

Install:

```bash
Add PubNub via Swift Package Manager or CocoaPods@10.1.6
```

PubNub delivers messages worldwide in less than 30 ms. Send a message to one recipient or broadcast to thousands of subscribers.

For higher-level conceptual details on publishing and subscribing, refer to [Connection Management](https://www.pubnub.com/docs/general/setup/connection-management) and to [Publish Messages](https://www.pubnub.com/docs/general/messages/publish).

## Publish

`publish()` sends a message to all channel subscribers. PubNub replicates the message across its points of presence and delivers it to all subscribed clients on that channel. All publish calls are performed asynchronously.

### Prerequisites and limitations

* You must [initialize PubNub](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration) with the `publishKey`.
* You don't have to be subscribed to a channel to publish to it.
* You cannot publish to multiple channels simultaneously.

### Security

Secure messages with Transport Layer Security (TLS) or Secure Sockets Layer (SSL) by setting `ssl` to `true` during [initialization](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration). You can also [encrypt](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration#cryptomodule) messages.

### Message data

The `message` and `meta` arguments can contain any Swift type conforming to `JSONCodable`. Strings can include any UTF‑8 characters.

:::warning Don't JSON serialize
You should not JSON serialize the `message` and `meta` parameters when sending signals, messages, or files as the serialization is automatic. Pass the full object as the message/meta payload and let PubNub handle everything.
:::

### Size

The maximum message size is 32 KiB. This includes the escaped character count and the channel name. Aim for under 1,800 bytes for optimal performance.

If your message exceeds the limit, you'll receive a `Message Too Large` error. To learn more or calculate payload size, see [Message size limits](https://www.pubnub.com/docs/general/messages/publish#message-size-limit).

:::tip Need larger messages?
Our platform is optimized for payloads up to 32 KiB. PubNub supports larger messages, but increasing the limit requires a verification of compatibility with your use case.
Talk to [our team](https://www.pubnub.com/company/contact-sales/) to discuss increasing the message size limit for your use case.
:::

### Publish rate

You can publish as fast as bandwidth allows. There is a [soft throughput limit](https://www.pubnub.com/docs/general/setup/limits) because messages may drop if subscribers can't keep up.

For example, publishing 200 messages at once may cause the first 100 to drop if a subscriber hasn't received any yet. The in-memory queue stores only 100 messages.

### Custom message type

You can optionally provide the `customMessageType` parameter to add your business-specific label or category to the message, for example `text`, `action`, or `poll`.

### Best practices

* Publish to a channel serially (not concurrently).
* Verify a success return code (for example, check `Result.success`).
* Publish the next message only after a success return code.
* On failure, retry.
* Keep the in-memory queue under 100 messages to avoid drops.
* Throttle bursts to meet latency needs (for example, no more than 5 messages per second).

### Method(s)

To `Publish a message` you can use the following method(s) in the Swift SDK:

```swift
func publish(
    channel: String,
    message: JSONCodable,
    customMessageType: String? = nil,
    shouldStore: Bool? = nil,
    storeTTL: Int? = nil,
    meta: AnyJSON? = nil,
    shouldCompress: Bool = false,
    custom requestConfig: PubNub.RequestConfiguration = PubNub.RequestConfiguration(),
    completion: ((Result<Timetoken, Error>) -> Void)?
)
```

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| channel | String | Yes |  | The `channel` ID to publish to. |
| message | JSONCodable | Yes |  | The `message` to publish. |
| customMessageType | String? | Optional | `nil` | A case-sensitive, alphanumeric string from 3 to 50 characters describing the business-specific label or category of the message. Dashes `-` and underscores `_` are allowed. The value cannot start with special characters or the string `pn_` or `pn-`. Examples: `text`, `action`, `poll`. |
| shouldStore | Bool? | Optional | `nil` | If `true` the published message is stored in history. |
| storeTTL | Int? | Optional | `nil` | Set a per message time to live in Message Persistence. 1. If shouldStore = `true`, and `storeTTL` = 0, the message is stored with no expiry time. 2. If shouldStore = `true` and `storeTTL` = X (X is an Integer value), the message is stored with an expiry time of X hours. 3. If shouldStore is `false` or not specified, the message isn't stored and the `storeTTL` parameter is ignored. 4. If `storeTTL` isn't specified, then expiration of the message defaults back to the expiry value for the key. |
| meta | JSONCodable? | Optional | `nil` | Publish extra `meta` with the request. |
| shouldCompress | Bool | Optional | `false` | When `true`, the SDK uses HTTP POST to publish the messages. The message is sent in the BODY of the request, instead of the query string when HTTP GET is used. Also the messages are compressed thus reducing the size of the messages. |
| custom | PubNub.RequestConfiguration | Optional | `PubNub.RequestConfiguration()` | An object that allows for per-request customization of PubNub configuration or network session. For more information, refer to the [Request configuration](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration#request-configuration) section. |
| completion | ((Result<Timetoken, | Optional | `nil` | The async `Result` of the method call. |

#### Completion handler result

##### Success

The `Timetoken` of the published Message.

##### Failure

An `Error` describing the failure.

### Sample code

#### Publish a message to a channel

:::tip Reference code
This example is a self-contained code snippet ready to be run. It includes necessary imports and executes methods with console logging. Use it as a reference when working with other examples in this document.
:::

```swift
import PubNubSDK

// Initializes a PubNub object with the configuration
let pubnub = PubNub(
  configuration: PubNubConfiguration(
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId"
  )
)

// Publish a message to a channel
pubnub.publish(
  channel: "my-channel",
  message: "Hello from PubNub Swift SDK",
  customMessageType: "text-message"
) { result in
  switch result {
  case let .success(timetoken):
    print("Message Successfully Published at: \(timetoken)")
  case let .failure(error):
    print("Failed Response: \(error.localizedDescription)")
  }
}
```

:::note Subscribe to the channel
Before running the above publish example, either using the [Debug Console](https://www.pubnub.com/docs/console/) or in a separate script running in a separate terminal window, [subscribe to the same channel](#subscribe) that is being published to.
:::

### Other examples

#### Publish a dictionary object

```swift
/// Publish payload JSON equivalent to:
///
/// ```
/// {
///   "greeting": "hello",
///   "location": "right here"
///  }
/// ```
pubnub.publish(
  channel: "my_channel",
  message: ["greeting": "hello", "location": "right here"]
) { result in
  switch result {
  case let .success(timetoken):
    print("Message Successfully Published at: \(timetoken)")
  case let .failure(error):
    print("Failed Publish Response: \(error.localizedDescription)")
  }
}
```

#### Publish the above dictionary as a custom Swift Object

```swift
/// Ensure that your custom type implements `JSONCodable`
struct Message: JSONCodable {
  var greeting: String
  var location: String
}

/// Publish payload JSON equivalent to:
///
/// ```
/// {
///   "greeting": "hello",
///   "location": "right here"
///  }
/// ```
pubnub.publish(
  channel: "my_channel",
  message: Message(greeting: "hello", location: "right here")
) { result in
  switch result {
  case let .success(timetoken):
    print("Message Successfully Published at: \(timetoken)")
  case let .failure(error):
    print("Failed Publish Response: \(error.localizedDescription)")
  }
}
```

#### Mix and match types with custom objects

```swift
/// Ensure that your custom type implements `JSONCodable`
struct CustomMessage: JSONCodable {
  var greeting: String
  var location: Location
}

/// Ensure that your custom type implements `JSONCodable`
struct Location: JSONCodable {
  var lat: Double
  var long: Double
}

/// Publish payload JSON equivalent to:
///
/// ```
/// {
///   "greeting": "hello",
///   "location": {
///     "lat": 37.782486,
///     "long": -122.395344
///   }
/// }
/// ```
pubnub.publish(
  channel: "my_channel",
  message: CustomMessage(greeting: "hello", location: Location(lat: 37.782486, long: -122.395344))
) { result in
  switch result {
  case let .success(timetoken):
    print("Message Successfully Published at: \(timetoken)")
  case let .failure(error):
    print("Failed Publish Response: \(error.localizedDescription)")
  }
}
```

#### Publish an APNs2 push notification

```swift
// Publish a message to a channel with APNS and FCM payloads
let pushMessage = PubNubPushMessage(
  apns: PubNubAPNSPayload(
    aps: APSPayload(alert: .object(.init(title: "Apple Message")), badge: 1, sound: .string("default")),
    pubnub: [.init(targets: [.init(topic: "com.pubnub.swift", environment: .production)], collapseID: "SwiftSDK")],
    payload: "Push Message from PubNub Swift SDK"
  ),
  fcm: PubNubFCMPayload(
    payload: "Push Message from PubNub Swift SDK",
    target: .topic("com.pubnub.swift"),
    notification: FCMNotificationPayload(title: "Android Message"),
    android: FCMAndroidPayload(collapseKey: "SwiftSDK", notification: FCMAndroidNotification(sound: "default"))
  ),
  additional: "Push Message from PubNub Swift SDK"
)

pubnub.publish(
  channel: "my-channel",
  message: pushMessage
) { result in
  switch result {
  case let .success(timetoken):
    print("Message Successfully Published at: \(timetoken)")
  case let .failure(error):
    print("Failed Response: \(error.localizedDescription)")
  }
}
```

#### Root level push message object

```swift
public struct PubNubPushMessage: JSONCodable {
  
  /// The payload delivered via Apple Push Notification service (APNS)
  public let apns: PubNubAPNSPayload?

  /// The payload delivered via Firebase Cloud Messaging service (FCM)
  public let fcm: PubNubFCMPayload?

  /// Additional message payload sent outside of the push notification
  ///
  /// In order to guarantee valid JSON any scalar values will be assigned to the `data` key.
  /// Non-scalar values will retain their coding keys.
  public var additionalMessage: JSONCodable?
}
```

## Fire

The fire endpoint sends a message to Functions event handlers and [Illuminate](https://www.pubnub.com/docs/illuminate/business-objects/external-data-sources). The message goes directly to handlers registered on the target channel and triggers their execution. The handler can read the request body. Messages sent via `fire()` aren't replicated to subscribers and aren't stored in history.

### Method(s)

To `Fire a message` you can use the following method(s) in the Swift SDK:

```swift
func fire(
    channel: String,
    message: JSONCodable,
    meta: JSONCodable? = nil,
    custom requestConfig: PubNub.RequestConfiguration = PubNub.RequestConfiguration(),
    completion: ((Result<Timetoken, Error>) -> Void)?
)
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | The `channel` ID to fire to. |
| `message` *Type: JSONCodableDefault: n/a | The `message` to fire. |
| `meta`Type: JSONCodable?Default: nil | Publish extra `meta` with the request. |
| `custom`Type: [PubNub.RequestConfiguration](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration#request-configuration)Default: `PubNub.RequestConfiguration()` | An object that allows for per-request customization of PubNub configuration or network session. For more information, refer to the [Request configuration](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration#request-configuration) section. |
| `completion`Type: `((Result<Timetoken, Error>) -> Void)?`Default: `nil` | The async `Result` of the method call. |

#### Completion handler result

##### Success

The `Timetoken` of the published Message.

##### Failure

An `Error` describing the failure.

### Sample code

#### Fire a message to a channel

```swift
// Publish a message to PubNub Functions Event Handlers
pubnub.fire(
  channel: "my-channel",
  message: "Hello from PubNub Swift SDK"
) { result in
  switch result {
  case let .success(timetoken):
    print("Message Successfully Published at: \(timetoken)")
  case let .failure(error):
    print("Failed Response: \(error.localizedDescription)")
  }
}
```

## Signal

The `signal()` function sends a signal to all subscribers of a channel.

By default, signals are limited to a message payload size of `64` bytes. This limit applies only to the payload, and not to the URI or headers. If you require a larger payload size, please [contact support](https://www.pubnub.com/docs/mailto:support@pubnub.com).

### Method(s)

To `Signal a message` you can use the following method(s) in the Swift SDK:

```swift
func signal( 
  channel: String, 
  message: JSONCodable,
  customMessageType: String? = nil,
  custom requestConfig: PubNub.RequestConfiguration = PubNub.RequestConfiguration(),
  completion: ((Result<Timetoken, Error>) -> Void)?
)
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | The channel ID to send a signal to. |
| `message` *Type: JSONCodableDefault: n/a | The message to signal. |
| `customMessageType`Type: String?Default: `nil` | A case-sensitive, alphanumeric string from 3 to 50 characters describing the business-specific label or category of the message. Dashes `-` and underscores `_` are allowed. The value cannot start with special characters or the string `pn_` or `pn-`. Examples: `text`, `action`, `poll`. |
| `custom`Type: [PubNub.RequestConfiguration](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration#request-configuration)Default: `PubNub.RequestConfiguration()` | An object that allows for per-request customization of PubNub configuration or network session. For more information, refer to the [Request configuration](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration#request-configuration) section. |
| `completion`Type: `((Result<Timetoken, Error>) -> Void)?`Default: `nil` | The async `Result` of the method call. |

#### Completion handler result

##### Success

The `Timetoken` of the published Message.

##### Failure

An `Error` describing the failure.

### Sample code

#### Signal a message to a channel

```swift
// Send a signal to a channel
pubnub.signal(
  channel: "my-channel",
  message: "Hello from PubNub Swift SDK",
  customMessageType: "text-message-signalled"
) { result in
  switch result {
  case let .success(timetoken):
    print("Message Successfully Published at: \(timetoken)")
  case let .failure(error):
    print("Failed Response: \(error.localizedDescription)")
  }
}
```

## Subscribe

Subscribe opens a TCP socket and listens for messages and events on a specified entity or set of entities. Set `subscribeKey` during [initialization](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration).

:::tip Conceptual overview
For more general information about subscriptions, refer to [Subscriptions](https://www.pubnub.com/docs/general/channels/subscribe).
:::

Entities are [first-class citizens](https://en.wikipedia.org/wiki/First-class_citizen) that expose their APIs. You can subscribe using the PubNub client or directly on a specific entity:

* [ChannelRepresentation](#create-channels)
* [ChannelGroupRepresentation](#create-a-channel-group)
* [UserMetadataRepresentation](#create-user-metadata)
* [ChannelMetadataRepresentation](#create-channel-metadata)

After `subscribe()`, the client receives new messages. Configure [automaticRetry](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration#initializers) to reconnect and fetch available messages after a disconnect.

### Subscription scope

Subscriptions let you attach listeners for specific real-time update types. Your app receives messages and events through those listeners. There are two types:

* [Subscription](#create-a-subscription): created from an entity and scoped to that entity (for example, a particular channel)
* [SubscriptionSet](#create-a-subscription-set): created from the PubNub client and scoped to the client (for example, all subscriptions created on a single `pubnub` object). A set can include one or more subscriptions.

One event listener receives all messages, signals, and events for the entities you subscribe to. To add listeners, see [Event listeners](#event-listeners).

### Create a subscription

An entity-level `Subscription` allows you to receive messages and events for only that entity for which it was created. Using multiple entity-level `Subscription`s is useful for handling various message/event types differently in each channel.

:::warning Keep a strong reference
You should keep a strong reference to every created subscription/subscription set because they must stay in memory to listen for updates. If you were to create a `Subscription`/`SubscriptionSet` and not keep a strong reference to it, Automatic Reference Counting (ARC) could deallocate the `Subscription` as soon as your code finishes executing.
:::

To create a subscription object, call the following method on any entity defined in the [Entities](#entities) section:

```swift
// Entity-based, local-scoped
func subscription(
  queue: DispatchQueue = .main,
  options: SubscriptionOptions = SubscriptionOptions.empty()
)
```

| Parameter | Description |
| --- | --- |
| `options`Type: `SubscriptionOptions` | `Subscription` [behavior configuration](#subscriptionoptions). |

### Create a subscription set

A client-level `SubscriptionSet` allows you to receive messages and events for all entities. A single `SubscriptionSet` is useful for similarly handling various message/event types in each channel.

:::warning Keep a strong reference
You should keep a strong reference to every created subscription/subscription set because they must stay in memory to listen for updates. If you were to create a `Subscription`/`SubscriptionSet` and not keep a strong reference to it, Automatic Reference Counting (ARC) could deallocate the `Subscription` as soon as your code finishes executing.
:::

To create a `SubscriptionSet`, call the following method on a `PubNub` instance:

```swift
// Client-based, general-scoped
func subscription(
    queue: DispatchQueue = .main,
    entities: any Collection<Subscribable>,
    options: SubscriptionOptions = SubscriptionOptions.empty()
) -> SubscriptionSet
```

| Parameter | Description |
| --- | --- |
| `queue`Type: `DispatchQueue` | An underlying queue to dispatch events. Defaults to the main queue. |
| `entities` *Type: `Collection<Subscribable>` | One or more entities to create a subscription of. Available values include: `ChannelRepresentation`, `ChannelGroupRepresentation`, `UserMetadataRepresentation`, `ChannelMetadataRepresentation`. |
| `options`Type: `SubscriptionOptions` | `Subscription` [behavior configuration](#subscriptionoptions). |

:::tip Add/remove sets
You can add and remove subscriptions to create new sets. Refer to the [Other examples](#other-examples-1) section for more information.
:::

#### SubscriptionOptions

`SubscriptionOptions` is the base class for all possible options. Available subclasses are:

| Option | Description |
| --- | --- |
| `ReceivePresenceEvents` | Whether presence updates for `userId`s should be delivered through the listener streams. For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel). |

### Method(s)

`Subscription` and `SubscriptionSet` use the same `subscribe()` method.

#### Subscribe

To subscribe, you can use the following method in the Swift SDK:

```swift
func subscribe(with: Timetoken? = nil)
```

| Parameter | Description |
| --- | --- |
| `with`Type: `Timetoken` | Timetoken from which to return any available cached messages. Message retrieval with timetoken is not guaranteed and should only be considered a best-effort service. If the value is not a 17-digit number, the provided value will be ignored. |

##### Sample code

```swift
import PubNubSDK

// Initializes a PubNub object with the configuration
let pubnub = PubNub(
  configuration: PubNubConfiguration(
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId"
  )
)

// Create a subscription for an example channel entity
let subscription = pubnub.channel("channel").subscription(options: ReceivePresenceEvents())
// Triggers the subscription
subscription.subscribe()
```

##### Other examples

###### Create a subscription set from 2 individual subscriptions

```swift
// Create a reference to example channel entity
let weatherChannelEntity = pubnub.channel("weather-updates")
// Create a reference to example channel group entity
let newsGroupEntity = pubnub.channelGroup("news-feed")

// Create a SubscriptionSet object from entities above
let subscriptionSet = pubnub.subscription(entities: [weatherChannelEntity, newsGroupEntity])

// Create a subscription for another channel entity to demonstrate
// adding and removing to/from a SubscriptionSet
let sportsSubscription = pubnub.channel("sports-scores").subscription()

// An example of how to add/remove a `sportsSubscription` to/from a SubscriptionSet
subscriptionSet.add(subscription: sportsSubscription)
subscriptionSet.remove(subscription: sportsSubscription)

// Triggers `.subscribe()` on the SubscriptionSet, initiating subscriptions to all contained entities
subscriptionSet.subscribe()
```

##### Returns

The `subscribe()` method doesn't have a return value.

## Entities

Entities are subscribable objects for which you can receive real-time updates (messages, events, etc).

* [ChannelRepresentation](#create-channels)
* [ChannelGroupRepresentation](#create-a-channel-group)
* [UserMetadataRepresentation](#create-user-metadata)
* [ChannelMetadataRepresentation](#create-channel-metadata)

The following methods can be called on a `PubNub` instance to create a local entity:

### Create channels

This method returns a local `ChannelRepresentation` entity.

```swift
func channel(_ name: String) -> ChannelRepresentation
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: `String` | The ID of the [channel](https://www.pubnub.com/docs/general/channels/overview) to create a subscription of. |

#### Sample code

```swift
pubnub.channel("channelName")
```

### Create a channel group

This method returns a local `ChannelGroupRepresentation` entity.

```swift
func channelGroup(_ name: String) -> ChannelGroupRepresentation
```

| Parameter | Description |
| --- | --- |
| `name` *Type: `String` | The name of the [channel group](https://www.pubnub.com/docs/general/channels/subscribe#channel-groups) to create a subscription of. |

#### Sample code

```swift
pubnub.channelGroup("channelGroupName")
```

### Create channel metadata

This method returns a local `ChannelMetadataRepresentation` entity.

```swift
func channelMetadata(_ name: String) -> ChannelMetadataRepresentation
```

| Parameter | Description |
| --- | --- |
| `name` *Type: `String` | The String identifier of the [channel metadata](https://www.pubnub.com/docs/general/metadata/channel-metadata) object to create a subscription of. |

#### Sample code

```swift
pubnub.channelMetadata("channelMetadataName")
```

### Create user metadata

This method returns a local `UserMetadataRepresentation` entity.

```swift
func userMetadata(_ name: String) -> UserMetadataRepresentation
```

| Parameter | Description |
| --- | --- |
| `name` *Type: `String` | The String identifier of the [user metadata](https://www.pubnub.com/docs/general/metadata/users-metadata) object to create a subscription of. |

#### Sample code

```swift
pubnub.userMetadata("userMetadataName")
```

## Event listeners

Messages and events are received in your app using a listener. This listener allows a single point to receive all messages, signals, and events.

You can attach listeners to the instances of [Subscription](#create-a-subscription), [SubscriptionSet](#create-a-subscription-set), and, in the case of the connection status, the PubNub client.

:::note No built-in event throttling
The PubNub SDK delivers every incoming event to your listener as it arrives — there is no built-in throttling or rate-limiting on the subscriber side. If you need to control how often your application processes events, wrap your listener callback with a throttle or debounce utility from your language or framework ecosystem.
To reduce the number of messages delivered to your client in the first place, use [Subscribe Filters](https://www.pubnub.com/docs/general/channels/subscribe-filters) to filter messages server-side before they reach your listener.
:::

### Add listeners

You can implement multiple listeners with the `onEvent` closure or register an event-specific listener that receives only a selected type, like `message` or `file`.

#### Method(s)

```swift
import PubNubSDK

// Initializes a PubNub object with the configuration
let pubnub = PubNub(
  configuration: PubNubConfiguration(
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId"
  )
)

// Create an example subscription for a channel
let subscription = pubnub
  .channel("channelName")
  .subscription()
```

```swift
// Defines a custom type that can be used to decode the message payload
struct Person: JSONCodable {
  var lastName: String
  var firstName: String
  var age: Int
}

// Add a listener for Message events
subscription.onMessage = { message in
  // Example showing how to decode the message payload as the custom Person type defined above
  if let person = try? message.payload.decode(Person.self) {
    print("Person object decoded successfully")
    print("Person details: \(person.lastName), \(person.firstName), \(person.age)")
  }
  // Example showing how to decode the message payload as a raw [String: Any] dictionary
  else if let dictionary = message.payload.codableValue.dictionaryOptional {
    print("Dictionary decoded successfully: \(dictionary)")
  }
  // Example showing how to decode the message payload as a raw [Any] array
  else if let array = message.payload.codableValue.arrayOptional {
    print("Array decoded successfully: \(array)")
  }
  // Example showing how to decode the message payload as a String scalar value.
  // If you need other scalar types, you can use the properties listed below:
  //
  // - .intOptional - to decode payload as an Int value
  // - .boolOptional - to decode payload as a Bool value
  // - .doubleOptional - to decode payload as a Double value
  else if let scalarValue = message.payload.codableValue.stringOptional {
    print("Scalar value: \(scalarValue)")
  }
  // Fallback when the message payload cannot be decoded
  else {
    print("Failed to decode the message payload")
  }
}
```

```swift
// Add a listener to receive Presence events (requires a subscription with presence)
subscription.onPresence = { presenceChange in
  for action in presenceChange.actions {
    switch action {
    case let .join(uuids):
      print("Occupants joined at \(presenceChange.timetoken): \(uuids)")
    case let .leave(uuids):
      print("Occupants left at \(presenceChange.timetoken): \(uuids)")
    case let .timeout(uuids):
      print("Occupants timed-out at \(presenceChange.timetoken): \(uuids)")
    case let .stateChange(uuid, state):
      print("\(uuid) changed state to \(state) at \(presenceChange.timetoken)")
    }
  }
}
```

```swift
// Add a listener to receive Message Action events
subscription.onMessageAction = { messageActionEvent in
  switch messageActionEvent {
  case let .added(messageAction):
    print("Message action added in \(messageAction.channel) channel at message timetoken \(messageAction.messageTimetoken)")
  case let .removed(messageAction):
    print("A message reaction with the timetoken of \(messageAction.actionTimetoken) has been removed")
  }
}
```

```swift
// Add a listener to receive App Context events
subscription.onAppContext = { appContextEvent in
  switch appContextEvent {
  case let .userMetadataSet(changeset):
    print("User metadata changes detected for \(changeset.metadataId) at \(changeset.updated).")
    print("All changes made to the object: \(changeset.changes)")
    print("To apply these changes, fetch the relevant object and call `changeset.apply(to: otherChannelMetadata)`.")
  case let .userMetadataRemoved(metadataId):
    print("Metadata for UUID \(metadataId) removed")
  case let .channelMetadataSet(changeset):
    print("Channel metadata changes detected for \(changeset.metadataId) at \(changeset.updated).")
    print("All changes made to the object: \(changeset.changes)")
    print("To apply these changes, fetch the relevant object and call `changeset.apply(to: otherUserMetadata)`.")
  case let .channelMetadataRemoved(metadataId: metadataId):
    print("Metadata for channel \(metadataId) removed")
  case let .membershipMetadataSet(membership):
    print("Membership set between \(membership.userMetadataId) and \(membership.channelMetadataId)")
  case let .membershipMetadataRemoved(membership):
    print("Membership removed between \(membership.userMetadataId) and \(membership.channelMetadataId)")
  }
}
```

```swift
// Add a listener to receive File events
subscription.onFileEvent = { fileEvent in
  if case let .uploaded(fileInfo) = fileEvent {
    print("File uploaded: \(fileInfo)")
  }
}
```

```swift
// Add a batched subscription event that possibly contains multiple events
subscription.onEvents = { events in
  print("Received events: \(events)")
}
```

```swift
// Add a listener to capture single event
subscription.onEvent = { event in
  switch event {
  case let .messageReceived(message):
    print("Message Received: \(message) Publisher: \(message.publisher ?? "defaultUUID")")
  case let .signalReceived(signal):
    print("Signal Received: \(signal)")
  case let .presenceChanged(presence):
    print("Presence event: \(presence)")
  case let .appContextChanged(appContextEvent):
    print("App Context change event: \(appContextEvent)")
  case let .messageActionChanged(messageActionEvent):
    print("Message Reaction event: \(messageActionEvent)")
  case let .fileChanged(fileEvent):
    print("File event: \(fileEvent)")
  }
}
```

### Add connection status listener

The PubNub client has a listener dedicated to handling connection status updates.

:::warning Client scope
This listener is only available on the `PubNub` object.
:::

#### Method(s)

```swift
var onConnectionStateChange: ((ConnectionStatus) -> Void)?
```

#### Sample code

```swift
// Sets a callback to handle connection state changes
pubnub.onConnectionStateChange = { newStatus in
  print("Connection status: \(newStatus)")
}
```

#### Returns

The subscription status. For information about available statuses, refer to [SDK statuses](https://www.pubnub.com/docs/general/setup/connection-management#sdk-statuses).

## Clone

Create a clone of an existing subscription with the same subscription state but an empty closures of real-time event listeners.

### Method(s)

```swift
// Method in the `Subscription` class
func clone() -> Subscription
// Method in the `SubscriptionSet` class
func clone() -> SubscriptionSet
```

### Sample code

```swift
let subscriptionSet = pubnub.subscription(
  entities: [pubnub.channel("channel"), pubnub.channelGroup("channelGroup")],
  options: ReceivePresenceEvents()
)
let subscription = pubnub
  .channel("channelName")
  .subscription()

let clonedSubscriptionSet = subscriptionSet.clone()
let clonedSubscription = subscription.clone()
```

### Returns

A new instance of the subscription object with an empty event dispatcher.

## Unsubscribe

Stop receiving real-time updates from a [Subscription](#create-a-subscription) or a [SubscriptionSet](#create-a-subscription-set).

### Method(s)

```swift
func unsubscribe()
```

### Sample code

```swift
subscription.unsubscribe()
subscriptionSet.unsubscribe()
```

### Returns

None

## Unsubscribe all

Remove the client's active subscriptions from all channels. It clears out the list of channels the client is currently listening to.

:::warning Client scope
This method is only available on the `PubNub` object.
:::

### Method(s)

```swift
func unsubscribeAll()
```

### Sample code

```swift
// Unsubscribes from all channels and channel groups
pubnub.unsubscribeAll()
```

### Returns

None

## Subscribe (old)

:::warning Not recommended
The use of this method is discouraged. Use [Subscribe](#subscribe) instead.
:::

#### Receive messages

Your app receives messages and events via event listeners. The event listener is a single point through which your app receives all the messages, signals, and events that are sent in any channel you are subscribed to.

For more information about adding a listener, refer to the [Event Listeners](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration#event-listeners) section.

#### Description

This function causes the client to create an open TCP socket to the PubNub Real-Time Network and begin listening for messages on a specified `channel` ID. To subscribe to a `channel` ID the client must send the appropriate `subscribeKey` at initialization.

By default a newly subscribed client will only receive messages published to the channel after the `subscribe()` call completes.

The PubNub Swift SDK removes (dedupes) messages automatically if they have the same timetoken, publisher, and payload.

:::warning Unsubscribing from all channels
**Unsubscribing** from all channels, and then **subscribing** to a new channel Y is not the same as subscribing to channel Y and then unsubscribing from the previously-subscribed channel(s). Unsubscribing from all channels resets the last-received `timetoken` and thus, there could be some gaps in the subscription that may lead to message loss.
:::

#### Method(s)

To `Subscribe to a channel` you can use the following method(s) in the Swift SDK:

```swift
func subscribe(
    to channels: [String],
    and channelGroups: [String] = [],
    at timetoken: Timetoken? = nil,
    withPresence: Bool = false
)
```

| Parameter | Description |
| --- | --- |
| `to` *Type: [String]Default: n/a | An array of channels to subscribe to. |
| `and`Type: [String]Default: `[]` | An array of channel groups to subscribe to. |
| `at`Type: Timetoken?Default: `nil` | The timetoken integer to start the subscription from. |
| `withPresence`Type: BoolDefault: `false` | If `true` it also subscribes to presence events on the specified channels. |
| `filterOverride`Type: String?Default: `nil` | Overrides the previous filter on the next successful request |

#### Sample code

Subscribe to a channel:

```swift
pubnub.subscribe(to: ["my_channel"])
```

:::note Event listeners
The response of the call is handled by adding a Listener. Please see the [Listeners section](https://www.pubnub.com/docs/sdks/swift/api-reference/configuration#event-listeners) for more details. Listeners should be added before calling the method.
:::

#### Other examples

##### Subscribing to multiple channels

It's possible to subscribe to more than one channel using the [Multiplexing](https://www.pubnub.com/docs/general/channels/subscribe#channel-multiplexing) feature. The example shows how to do that using an array to specify the channel names.

:::note Alternative subscription methods
You can also use [Wildcard Subscribe](https://www.pubnub.com/docs/general/channels/subscribe#wildcard-subscribe) and [Channel Groups](https://www.pubnub.com/docs/general/channels/subscribe#channel-groups) to subscribe to multiple channels at a time. To use these features, the *Stream Controller* add-on must be enabled on your keyset in the [Admin Portal](https://admin.pubnub.com).
:::

```swift
pubnub.subscribe(to: ["my_channel", "my_channel-2", "my_channel-3"])
```

##### Subscribing to a Presence channel

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/). For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel).
:::

For any given channel there is an associated Presence channel. You can subscribe directly to the channel by appending `-pnpres` to the channel name. For example the channel named `my_channel` would have the presence channel named `my_channel-pnpres`.

```swift
pubnub.subscribe(
  to: ["my_channel"],
  withPresence: true
)
```

##### Wildcard subscribe to channels

:::note Requires Stream Controller add-on
This method requires that the *Stream Controller* add-on is enabled for your key in the [Admin Portal](https://admin.pubnub.com/) (with Enable Wildcard Subscribe checked). Read the [support page](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) on enabling add-on features on your keys.
:::

Wildcard subscribes allow the client to subscribe to multiple channels using wildcard. For example, if you subscribe to `a.*` you will get all messages for `a.b`, `a.c`, `a.x`. The wildcarded `*` portion refers to any portion of the channel string name after the `dot (.)`.

```swift
pubnub.subscribe(to: ["a.b.*"])
```

:::note Wildcard grants and revokes
Only one level (`a.*`) of wildcarding is supported. If you grant on `*` or `a.b.*`, the grant will treat `*` or `a.b.*` as a single channel named either `*` or `a.b.*`. You can also revoke permissions from multiple channels using wildcards but only if you previously granted permissions using the same wildcards. Wildcard revokes, similarly to grants, only work one level deep, like `a.*`.
:::

##### Subscribe to a channel group

:::note Requires Stream Controller add-on
This method requires that the *Stream Controller* add-on is enabled for your key in the [Admin Portal](https://admin.pubnub.com/). Read the [support page](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) on enabling add-on features on your keys.
:::

```swift
pubnub.subscribe(
  to: [],
  and: ["my_group"]
)
```

##### Subscribe to the Presence channel of a channel group

:::note Requires Stream Controller and Presence add-ons
This method requires both the *Stream Controller* and *Presence* add-ons are enabled for your key in the [Admin Portal](https://admin.pubnub.com/). Read the [support page](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) on enabling add-on features on your keys.
:::

```swift
pubnub.subscribe(
  to: [],
  and: ["my_group"],
  withPresence: true
)
```

##### Subscribing to multiple channel groups

:::note Requires Stream Controller add-on
This method requires that the *Stream Controller* add-on is enabled for your key in the [Admin Portal](https://admin.pubnub.com/). Read the [support page](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) on enabling add-on features on your keys.
:::

```swift
pubnub.subscribe(
  to: [],
  and: ["my_group", "my_group-2", "my_group-3"]
)
```

##### Subscribing to a channel and channel group simultaneously

:::note Requires Stream Controller add-on
This method requires that the *Stream Controller* add-on is enabled for your key in the [Admin Portal](https://admin.pubnub.com/). Read the [support page](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) on enabling add-on features on your keys.
:::

```swift
pubnub.subscribe(
  to: ["my_channel"],
  and: ["my_group"]
)
```

#### Event listeners

You can be notified of connectivity status, message, and presence notifications via the listeners.

Listeners should be added before calling the method.

##### Add listeners

```swift
import PubNubSDK

// Initializes a PubNub object with the configuration
let pubnub = PubNub(
  configuration: PubNubConfiguration(
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId"
  )
)

// Create a new listener instance
let listener = SubscriptionListener()

// Add listener event callbacks
listener.didReceiveSubscription = { event in
  switch event {
  case let .messageReceived(message):
    print("Message Received: \(message) Publisher: \(message.publisher ?? "defaultUUID")")
  case let .connectionStatusChanged(status):
    print("Status Received: \(status)")
  case let .presenceChanged(presence):
    print("Presence Received: \(presence)")
  case let .subscribeError(error):
    print("Subscription Error \(error)")
  default:
    break
  }
}

// Add a listener to enable the receiving of subscription events.
// Ensure that you call `pubnub.add(listener)` before subscribing to channels or channel groups
pubnub.add(listener)
```

:::note How to check UUID
You can check the UUID of the publisher of a particular message by checking the `message.publisher` property in the subscription listener.
:::

##### Remove listeners

The `SubscriptionListener` can be removed by either calling `listener.cancel()`, or by letting it fall out of scope and be removed as an autoreleased object.

##### Listener subscription Events

This is the list of `SubscriptionEvent` case types that can be emitted from `didReceiveSubscription`, or grouped together using `didReceiveBatchSubscription`. Each event case also has a standalone listener that can save code space, but will be functionally equivalent to using `didReceiveSubscription`.

| Case | Type | Standalone Listener | Description |
| --- | --- | --- | --- |
| messageReceived | `PubNubMessage` | `didReceiveMessage` | Messages sent to subscribed channels/groups |
| signalReceived | `PubNubMessage` | `didReceiveSignal` | Signals sent to subscribed channels/groups |
| connectionStatusChanged | `ConnectionStatus` | `didReceiveStatus` | Changes in the connection to the PubNub system |
| subscriptionChanged | `SubscriptionChangeEvent` | `didReceiveSubscriptionChange` | Notifies when channels/groups are subscribed or unsubscribed |
| presenceChanged | `PubNubPresenceChange` | `didReceivePresence` | Presence changes on subscribed channels/groups tracking presence |
| uuidMetadataSet | `PubNubUUIDMetadataChangeset` | `didReceiveObjectMetadataEvent` | UUID metadata was set |
| uuidMetadataRemoved | `String` | `didReceiveObjectMetadataEvent` | UUID metadata was removed |
| channelMetadataSet | `PubNubChannelMetadataChangeset` | `didReceiveObjectMetadataEvent` | Channel metadata was set |
| channelMetadataRemoved | `String` | `didReceiveObjectMetadataEvent` | Channel metadata was removed |
| membershipMetadataSet | `PubNubMembershipMetadata` | `didReceiveObjectMetadataEvent` | Membership metadata was set |
| membershipMetadataRemoved | `PubNubMembershipMetadata` | `didReceiveObjectMetadataEvent` | Membership metadata was removed |
| messageActionAdded | `PubNubMessageAction` | `didReceiveMessageAction` | A `PubNubMessageAction` was added to a published message |
| messageActionRemoved | `PubNubMessageAction` | `didReceiveMessageAction` | A `PubNubMessageAction` was removed from a published message |
| subscribeError | `PubNubError` | `subscribeError` | Any error that might have occurred during the subscription stream |

#### Sample code

This is an example using `didReceiveBatchSubscription` to allow you to receive multiple events per event call.

```swift
listener.didReceiveBatchSubscription = { events in
  for event in events {
    switch event {
    case .messageReceived(let message):
      print("The \(message.channel) channel received a message at \(message.published).")
      print("The channel group or wildcard subscription match (if exists): \(String(describing: message.subscription)).")
      print("Message payload: \(message.payload). Sent by: \(message.publisher ?? "unknown").")

    case .signalReceived(let signal):
      print("The \(signal.channel) channel received a signal at \(signal.published).")
      print("The channel group or wildcard subscription match (if exists): \(String(describing: signal.subscription)).")
      print("Signal payload: \(signal.payload). Sent by: \(signal.publisher ?? "unknown").")

    case .connectionStatusChanged(let connectionChange):
      switch connectionChange {
      case let .subscriptionChanged(channels, groups):
        print("The SDK has subscribed to new channels or channel groups after the initial connection")
        print("Currently subscribed channels: \(channels)")
        print("Currently subscribed groups: \(channels)")
      case .connected:
        print("Connection status: connected!")
      case .disconnected:
        print("Connection status: disconnected!")
      case let .connectionError(error):
        print("Connection status: connection error! \(error.localizedDescription)")
      case let .disconnectedUnexpectedly(error):
        print("Connection status: disconnected unexpectedly due to error! \(error.localizedDescription)")
      }

    case .subscriptionChanged(let subscribeChange):
      switch subscribeChange {
      case let .subscribed(channels, groups):
        print("Subscribed to channels: \(channels), groups: \(groups).")
      case let .responseHeader(channels, groups, previous, next):
        print("Response received from channels: \(channels), groups: \(groups). Previous timetoken: \(previous?.timetoken ?? 0). Next timetoken: \(next?.timetoken ?? 0).")
      case let .unsubscribed(channels, groups):
        print("Unsubscribed from channels: \(channels), groups: \(groups).")
      }

    case .presenceChanged(let presenceChange):
      print("Presence updated for channel \(presenceChange.channel)")
      print("Channel occupancy \(presenceChange.occupancy)")

      for action in presenceChange.actions {
        switch action {
        case let .join(uuids):
          print("Occupants joined at \(presenceChange.timetoken): \(uuids).")
        case let .leave(uuids):
          print("Occupants left at \(presenceChange.timetoken): \(uuids).")
        case let .timeout(uuids):
          print("Occupants timed-out at \(presenceChange.timetoken): \(uuids).")
        case let .stateChange(uuid, state):
          print("\(uuid) updated state to \(state) at \(presenceChange.timetoken).")
        }
      }

    case .uuidMetadataSet(let uuidMetadataChange):
      print("UUID metadata changes detected for \(uuidMetadataChange.metadataId) at \(uuidMetadataChange.updated).")
      print("All changes made to the object: \(uuidMetadataChange.changes)")
      print("To apply these changes, fetch the relevant object and call `uuidMetadataChange.apply(to: otherUUIDMetadata)`.")

    case .uuidMetadataRemoved(let metadataId):
      print("Metadata for UUID \(metadataId) has been removed.")

    case .channelMetadataSet(let channelMetadata):
      print("Channel metadata changes detected for \(channelMetadata.metadataId) at \(channelMetadata.updated).")
      print("All changes made to the object: \(channelMetadata.changes)")
      print("To apply these changes, fetch the relevant object and call `channelMetadata.apply(to: otherChannelMetadata)`.")

    case .channelMetadataRemoved(let metadataId):
      print("Metadata for channel \(metadataId) has been removed.")

    case .membershipMetadataSet(let membership):
      print("Membership established between UUID \(membership.uuidMetadataId) and channel \(membership.channelMetadataId).")

    case .membershipMetadataRemoved(let membership):
      print("Membership removed between UUID \(membership.uuidMetadataId) and channel \(membership.channelMetadataId).")

    case .messageActionAdded(let messageAction):
      print("Message action added in \(messageAction.channel) channel at message timetoken \(messageAction.messageTimetoken).")
      print("Action created at \(messageAction.actionTimetoken) with type \(messageAction.actionType) and value \(messageAction.actionValue).")

    case .messageActionRemoved(let messageAction):
      print("The \(messageAction.channel) channel received a message at \(messageAction.messageTimetoken)")
      print("A message reaction with the timetoken of \(messageAction.actionTimetoken) has been removed")

    case .subscribeError(let error):
      print("Subscription error occurred: \(error.localizedDescription). Check if a `disconnectedUnexpectedly` status also happened; if so, restart the subscription.")

    case let .fileUploaded(fileEvent):
      print("A file was uploaded: \(fileEvent)")
    }
  }
}
```

#### Other examples

For `didReceiveSubscription`, simply rename the remove the `for...in` loop while keeping the event `switch`:

```swift
listener.didReceiveSubscription = { event in
  switch event {
    // Same content as the above example
  default:
    break
  }
}
```

## Unsubscribe (old)

:::warning Not recommended
The use of this method is discouraged. Use [Unsubscribe](#unsubscribe) instead.
:::

When subscribed to a single channel, this function causes the client to issue a `leave` from the `channel` and close any open socket to the PubNub Network. For multiplexed channels, the specified `channel`(s) will be removed and the socket remains open until there are no more channels remaining in the list.

:::warning Unsubscribing from all channels
**Unsubscribing** from all channels, and then **subscribing** to a new channel Y is not the same as subscribing to channel Y and then unsubscribing from the previously-subscribed channel(s). Unsubscribing from all channels resets the last-received `timetoken` and thus, there could be some gaps in the subscription that may lead to message loss.
:::

#### Method(s)

To `Unsubscribe from a channel` you can use the following method(s) in the Swift SDK:

```swift
func unsubscribe(from channels: [String], and channelGroups: [String] = [])
```

| Parameter | Description |
| --- | --- |
| `from` *Type: ArrayDefault: n/a | The list of channels to `unsubscribe` from. |
| `and`Type: ArrayDefault: `[]` | The list of channel groups to `unsubscribe` from. |
| `presenceOnly`Type: BoolDefault: `false` | If `true` it only unsubscribes from presence events on the specified channels. |

#### Sample code

Unsubscribe from a channel:

```swift
pubnub.unsubscribe(from: ["my_channel"])
```

#### Other examples

##### Unsubscribing from multiple channels

:::note Requires Stream Controller add-on
This method requires that the *Stream Controller* add-on is enabled for your key in the [Admin Portal](https://admin.pubnub.com/). Read the [support page](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) on enabling add-on features on your keys.
:::

```swift
pubnub.unsubscribe(from: ["my_channel", "my_channel-2", "my_channel-3"])
```

##### Unsubscribing from multiple channel groups

:::note Requires Stream Controller add-on
This method requires that the *Stream Controller* add-on is enabled for your key in the [Admin Portal](https://admin.pubnub.com/). Read the [support page](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) on enabling add-on features on your keys.
:::

```swift
pubnub.unsubscribe(
  from: [],
  and: ["my_channel", "my_channel-2", "my_channel-3"]
)
```

## Unsubscribe all (old)

:::warning Deprecated
This method is deprecated. Use [Unubscribe all](#unsubscribe-all) instead.
:::

Unsubscribe from all channels and all channel groups

#### Method(s)

```swift
func unsubscribeAll()
```

#### Sample code

```swift
pubnub.unsubscribeAll()
```

#### Returns

None

## Terms in this document

* **Access Manager** - A cryptographic, token-based permission administrator that allows you to regulate clients' access to PubNub resources, such as channels, channel groups, and user IDs.
* **Action** - The type of activity (procedure) to execute when a condition is satisfied (for example, sending a message).
* **Billing alert notification** - A means of informing a user that a billing alert has been triggered. Before notifications can happen, a billing alert must be triggered first.
* **Business Object** - A container for data fields and metrics that defines aggregations and data sources.
* **Channel** - A pathway for sending and receiving messages between devices, created automatically when you first use it, that can handle any number of users and messages for different communication needs, like 1-1 text chats, group conversations, and other data streaming.
* **Channel pattern** - A way to group and analyze channel data to track performance metrics like message counts and user engagement over time with PubNub Insights.
* **Condition** - A requirement that must be satisfied or evaluated to true for an action to be executed. Input in a decision table.
* **Cryptor** - An implementation of a specific cryptographic algorithm used for data encryption/decryption that adheres to a standard interface.
* **Dashboard** - A collection of widgets (charts) that give an overview of the metrics one is evaluating.
* **Data fields** - Data you want Illuminate to track. These can be quantitative (measures), like "Number" or "Timestamp" or qualitative (dimensions) values, like "String" that can be used to categorize and segment data. Data fields can be aggregated and calculated.
* **Decision** - A collection (or decision table) of conditions and actions. When conditions are satisfied, the corresponding actions are triggered as per defined rules.
* **End Customer** - A customer of a PubNub partner. End customers do not have direct access to the Admin Portal. Instead, they interact with PubNub products—such as Illuminate—through the partner’s portal, where PubNub services are embedded. They can create PubNub objects only within this partner-provided environment.
* **Entity** - A subscribable object within a PubNub SDK that allows you to perform context-specific operations.
* **Listener** - A function or objectthat reacts to events or messages, like new chat messages or connection updates, letting your app respond in real-time.
* **Mapped/Unmapped** - Whether the data source for a data field has been defined or the action has been configured.
* **MCP Server** - A Model Context Protocol server that coordinates communication and synchronization between AI agents, clients, or services, such as Cursor IDE and Windsurf.
* **Message** - A unit of data transmitted between clients or between a client and a server in PubNub, containing information such as text, binary data, or structured data formats like JSON. Messages are sent over channels and can be tracked for delivery and read status.
* **Metric** - What exactly is evaluated using measures and dimensions (collectively called data fields), as well as aggregation functions.
* **Module** - A Functions v1 container that groups related functions for configuration and deployment on an app’s keysets.
* **Origin** - The subdomain used to establish a connection to the PubNub network that allows your application's traffic to appear like it's coming from your own domain.
* **Package** - A Functions v2 container that groups Functions, tracks Revisions, and is deployed to keysets.
* **Partner** - A PubNub customer who resells PubNub products, such as Illuminate, to their own customers. Partners have access to the Admin Portal, enabling them to create and manage PubNub objects for themselves or on behalf of their end customers.
* **Publish Key** - A unique identifier that allows your application to send messages to PubNub channels. It's part of your app's credentials and should be kept secure.
* **PubNub** - PubNub is a real-time messaging platform that provides APIs and SDKs for building scalable applications. It handles the complex infrastructure of real-time communication, including: Message delivery and persistence, Presence detection, Access control, Push notifications, File sharing, Serverless processing with Functions and Events & Actions, Analytics and monitoring with BizOps Workspace, AI-powered insights with Illuminate.
* **Push token** - A device identifier issued by a push provider (APNs or FCM) used to register a device for receiving mobile push notifications.
* **Rule** - A definition (row in a decision table) stating which action should be triggered for which condition.
* **Service Integration** - A machine identity that represents a program or service consuming the Admin API, scoped to your account and authenticated using expirable API keys with configurable permissions.
* **Signal** - A non-persistent message limited to 64 bytes designed for high-volume usecases where the the most recent data is relevant, like GPS location updates.
* **Subscribe Key** - A unique identifier that allows your application to receive messages from PubNub channels. It's part of your app's credentials and should be kept secure.
* **Timetoken** - A unique identifier for each message that represents the number of 100-nanosecond intervals since January 1, 1970, for example, 16200000000000000.
* **Trigger details** - A set of predefined criteria for a given billing alert. When met, billing alert notifications are generated.
* **User** - An individual or entity that interacts with a system, application, or service. In PubNub, a user typically refers to someone who sends or receives messages through the platform, identified by a unique user ID or username.
* **User ID** - UTF-8 encoded, unique string of up to 92 characters used to identify a single client (end user, device, or server) that connects to PubNub.
* **Vibe Coding** - A way to build applications in an intuitive, relaxed, and improvisational manner, using AI tools and natural language descriptions.