Presence

In your chat app, you might want to graphically show up-to-date information on all users present in an app or on a given channel, showing if they are online, offline, active, or away. You may also want to let other chat users know when was the last time a given user was online.

Chat SDK provides methods and options to determine user presence on the channel and the app (global) level. Additionally, it provides a way of checking the last time the user performed some online activity in the app based on a Unix timestamp.

To find out the channel presence of a user, Chat SDK uses the PubNub Presence API. It provides a set of convenience methods for checking which channels a given user is subscribed to. Importantly, you can stream presence events and always get real-time information about the user's channel presence. You can also set dynamic custom state for users on one or more channels. This custom state persists on a channel as long as the user stays subscribed. Some examples of custom states are to add your score, game state, or location in an application if it changes frequently.

For global (app) presence, however, Chat SDK couldn't rely on Presence API as it doesn't support global user presence, but is limited to the context of a given channel. To fill that gap, the Chat SDK offers an optional lastActiveTimestamp property on each User object that states when was the last time the user was active in an app.

Suppose you want to track users' global presence in your chat app (for example, to see a user's current online state when browsing the users). In that case, you can configure your app to monitor this property and set an interval to update it. You can later use a dedicated active method to retrieve that information and display it across the app or in the context of a given channel, if you like. Contrary to the channel presence, global user presence info is not real-time information and depends on how often you update it - the default value is 600 seconds (10 minutes) and the minimum value is 60 seconds (1 minute). You can set a preferred value during the Chat SDK initialization through the storeUserActivityTimestamps parameter.

Read the sections to learn how to use all Chat SDK options and what configuration is required to implement channel and global presence in your app.

Channel presence

These methods let you monitor who is subscribed to a given channel ("present" on that channel).

Requires Presence

All channel presence methods in this section require that Presence is enabled for your app's keyset in the Admin Portal.

You can retrieve similar information for presence with different methods by calling them on the User, Channel, or Chat object. Depending on the chosen method, you must provide a different input information set.

Return channels where user is present

You can return a list of channels where a given user is present with:

  • wherePresent() called on the User object
  • wherePresent() called on the Chat object.

Both of these methods have the same name and give the same output. The only difference is that you call a given method either on the Chat or the User object. Depending on the object, you either have to specify the ID of the user whose presence you want to check or not because it's already known.

Method signature

These methods take the following parameters:

  • wherePresent() (on the User object)

    user.wherePresent() async throws -> [String]
  • wherePresent() (on the Chat object)

    chat.wherePresent(
    userId: String
    ) async throws -> [String]
Input
ParameterRequired in the User object methodRequired in the Chat object methodDescription
userId
Type: String
Default:
n/a
No
Yes
Unique identifier (up to 92 UTF-8 characters) of the user whose presence you want to check.
Output
ParameterDescription
[String]
List of all channel IDs on which the given user is present.

Basic usage

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 a list of channels on which the support_agent_15 user is present.

  • wherePresent() (on the User object)

    // Assuming you have a reference of type "ChatImpl" named "chat"
    Task {
    if let user = try await chat.getUser(userId: "support_agent_15") {
    let channels = try await user.wherePresent()
    debugPrint("User is present in the following channels: \(channels)")
    } else {
    debugPrint("User not found")
    }
    }
  • wherePresent() (on the Chat object)

    // Assuming you have a reference of type "ChatImpl" named "chat"
    Task {
    let channels = try await chat.wherePresent(userId: "support_agent_15")
    debugPrint("User \"support_agent_15\" is present in the following channels: \(channels)")
    }

Check user's channel presence

You can return information if the user is present on a specified channel with:

  • isPresentOn() called on the User object
  • isPresent() called on the Channel object.
  • isPresent() called on the Chat object.

All of these methods give the same output. The only difference is that you call a given method on the User, Channel, or Chat object. Depending on the object, you have to specify the ID of the user whose presence you want to check, the channel ID where you want to check user's presence, or both user and channel IDs.

Method signature

These methods take the following parameters:

  • isPresentOn() (on the User object)

    user.isPresentOn(
    channelId: String
    ) async throws -> Bool
  • isPresent() (on the Channel object)

    channel.isPresent(
    userId: String
    ) async throws -> Bool
  • isPresent() (on the Chat object)

    chat.isPresent(
    userId: String,
    channelId: String
    ) async throws -> Bool
Input
ParameterRequired in the User object methodRequired in the Channel object methodRequired in the Chat object methodDescription
userId
Type: String
Default:
n/a
No
Yes
Yes
Unique ID (up to 92 UTF-8 characters) of the user whose presence you want to check.
channelId
Type: String
Default:
n/a
Yes
No
Yes
Unique identifier of the channel where you want to check the user's presence.
Output
ParameterDescription
Bool
Returns information on whether a given user is present on a specified channel (true) or not (false) or an error.

Basic usage

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.

Find out if the support_agent_15 user is present on the support channel.

  • isPresentOn() (on the User object)
// User ID and Channel ID for the checking presence
let userId = "support_agent_15"
let channelId = "support_channel_123"

// Assuming you have a reference of type "ChatImpl" named "chat"
Task {
if let user = try await chat.getUser(userId: userId) {
let isPresent = try await user.isPresentOn(channelId: channelId)
debugPrint("User is present on the channel \(channelId): \(isPresent)")
} else {
debugPrint("User not found")
}
}
  • isPresent() (on the Channel object)
// User ID and Channel ID for the checking presence
let userId = "support_agent_15"
let channelId = "support_channel_123"

// Assuming you have a reference of type "ChatImpl" named "chat"
Task {
if let channel = try await chat.getChannel(channelId: channelId) {
let isPresent = try await channel.isPresent(userId: userId)
debugPrint("User \(userId) is present on the channel \(channelId): \(isPresent)")
} else {
debugPrint("Channel not found")
}
}
  • isPresent() (on the Chat object)
// User ID and Channel ID for the checking presence
let userId = "support_agent_15"
let channelId = "support_channel_123"

// Assuming you have a reference of type "ChatImpl" named "chat"
Task {
let isPresent = try await chat.isPresent(userId: userId, channelId: channelId)
debugPrint("User \(userId) is present on the channel \(channelId): \(isPresent)")
}

Return all users present on channel

You can return a list of users present on the given channel with:

  • whoIsPresent() called on the Channel object
  • whoIsPresent() called on the Chat object.

Both of these methods have the same name and give the same output. The only difference is that you call a given method either on the Chat or the Channel object. Depending on the object, you either have to specify the ID of the channel where you want to check all present users or not because it's already known.

Method signature

These methods take the following parameters:

  • whoIsPresent() (on the Channel object)

    channel.whoIsPresent() async throws -> [String]
  • whoIsPresent() (on the Chat object)

    chat.whoIsPresent(
    channelId: String
    ) async throws -> [String]
Input
ParameterRequired in the Channel object methodRequired in the Chat object methodDescription
channelId
Type: String
Default:
n/a
No
Yes
Unique identifier of the channel where you want to check all present users.
Output
ParameterDescription
[String]
List of all user IDs that are present on the given channel.

Basic usage

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 a list of users that are present on the support channel.

  • whoIsPresent() (on the Channel object)

    // Assuming you have a reference of type "ChatImpl" named "chat"
    Task {
    if let channel = try await chat.getChannel(channelId: "support_channel_123") {
    let userIds = try await channel.whoIsPresent()
    debugPrint("Users present on the channel: \(userIds)")
    } else {
    debugPrint("Channel not found")
    }
    }
  • whoIsPresent() (on the Chat object)

    // Assuming you have a reference of type "ChatImpl" named "chat"
    Task {
    let userIds = try await chat.whoIsPresent(channelId: "support_channel_123")
    debugPrint("Users present on the channel: \(userIds)")
    }

Get presence updates

Get up-to-date information about the real-time presence of users in the specified channel by subscribing to PubNub Presence events. The streamPresence() method lets you constantly track who connects to or disconnects from the channel and visually represent that in your chat app through some status, like offline, online, active, away, or any other.

Method signature

This method takes the following parameters:

channel.streamPresence() -> AsyncStream<[String]>
Input

This method doesn't take any parameters.

Output
ParameterDescription
AutoCloseable
An asynchronous stream that emits a value whenever users connect to or disconnect from the channel.

Basic usage

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 user presence updates on support channel.

// Assuming you have a reference of type "ChatImpl" named "chat"
Task {
if let channel = try await chat.getChannel(channelId: "support") {
for await userIds in channel.streamPresence() {
debugPrint("Current users present on 'support' channel: \(userIds)")
}
} else {
debugPrint("Channel not found")
}
}

Global presence

The Chat SDK lets you configure your app to track the user's last online activity - this gives near real-time visibility into the availability of other chat members, allowing you to see whether someone is offline or available and reach out to them to start immediate communication.

Using this online activity information provided by the Chat SDK, you can later configure your app to display different statuses next to user profiles, like offline, online, active, away or any other.

This feature relies on the lastActiveTimestamp property set in seconds on the User object. This property stands for the Unix timestamp (numeric value representing the number of seconds since January 1, 1970) for the last time the user was active in a chat app. To track this, you must explicitly state that when configuring your app during the Chat SDK initialization by:

  • Setting the storeUserActivityTimestamps parameter to true.
  • Deciding how frequently a user's online activity will be updated by configuring the storeUserActivityInterval option - the default value is set to 600 seconds (10 minutes) and the minimum value is 60 seconds (1 minute).

If you set these options, you can track a user's global presence through the active property that relies on the above setup. If the user showed no online activity within the defined period of time, they are considered inactive.

Check user's app presence

active is a property called on the User object that lets you check whether a user has recently been active in the chat app based on their last activity timestamp and a configured interval.

Required configuration

To track the user's online activity, you must first configure the storeUserActivityTimestamps and storeUserActivityInterval parameters when initializing the Chat SDK.

Method signature

This method has the following signature:

user.active
Input

This method doesn't take any parameters.

Output
ParameterDescription
Bool
Returned info on whether the user is active (true) or not active (false) on the channel. The returned value depends strictly on how you configure your chat app during initialization - if you set the storeUserActivityInterval parameter to the default 600 seconds (10 minutes) and the user has been active in the app within the last 10 minutes (based on their lastActiveTimestamp property), the active method returns true.

Basic usage

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.

Check if the user support_agent_15 has been recently active (assuming you configured the chat app to use the default activity interval value).

// Assuming you have a reference of type "ChatImpl" named "chat"
Task {
if let user = try await chat.getUser(userId: "support_agent_15") {
if user.active {
debugPrint("User \(user.id) is currently active.")
} else {
debugPrint("User \(user.id) is currently not active.")
}
} else {
debugPrint("User not found")
}
}

Check user's last online activity

Required configuration

To track the user's online activity, you must first configure the storeUserActivityTimestamps and storeUserActivityInterval parameters when initializing the Chat SDK.

Let's assume you configured your app to track the user's online activity and update it every 2 minutes. You can retrieve information on the user's last online activity directly from the User object, convert it to a human-readable date (using external date and time libraries), and display it next to the user's profile in your chat app. Thanks to that, other app users will be able to see the last time the given user was online.

Basic usage

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.

Show the Unix timestamp when support_agent_15 was last time active in an app.

// Assuming you have a reference of type "ChatImpl" named "chat"
Task {
if let user = try await chat.getUser(userId: "support_agent_15") {
debugPrint("Fetched user metadata with ID: \(user.id)")
debugPrint("Last active timestamp: \(user.lastActiveTimestamp)")
} else {
debugPrint("User not found")
}
}
Last updated on