Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
name: swift-chat-sdk
scm: github.com/pubnub/swift-chat-sdk
version: 0.33.0
version: 0.34.0
schema: 1
changelog:
- date: 2026-01-26
version: 0.34.0
changes:
- type: feature
text: "Add limit and offset parameters to whoIsPresent methods."
- date: 2025-12-10
version: 0.33.0
changes:
Expand Down Expand Up @@ -202,7 +207,7 @@ sdks:
- distribution-type: source
distribution-repository: GitHub release
package-name: PubNubSwiftChatSDK
location: https://github.com/pubnub/swift-chat-sdk/archive/refs/tags/0.33.0.zip
location: https://github.com/pubnub/swift-chat-sdk/archive/refs/tags/0.34.0.zip
supported-platforms:
supported-operating-systems:
iOS:
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ let package = Package(
)
],
dependencies: [
.package(url: "https://github.com/pubnub/kmp-chat", exact: "0.15.2-swift"),
.package(url: "https://github.com/pubnub/swift", exact: "9.3.2")
.package(url: "https://github.com/pubnub/kmp-chat", exact: "0.16.2-swift"),
.package(url: "https://github.com/pubnub/swift", exact: "10.1.2")
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
Expand Down
8 changes: 4 additions & 4 deletions PubNubSwiftChatSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 0.33.0;
MARKETING_VERSION = 0.34.0;
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS";
Expand Down Expand Up @@ -1024,7 +1024,7 @@
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 0.33.0;
MARKETING_VERSION = 0.34.0;
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS";
Expand Down Expand Up @@ -1137,15 +1137,15 @@
repositoryURL = "https://github.com/pubnub/kmp-chat";
requirement = {
kind = exactVersion;
version = "0.15.2-swift";
version = "0.16.2-swift";
};
};
3DCF7DFA2CD0FFCC00889326 /* XCRemoteSwiftPackageReference "swift" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/pubnub/swift";
requirement = {
kind = exactVersion;
version = 9.3.2;
version = 10.1.2;
};
};
/* End XCRemoteSwiftPackageReference section */
Expand Down
9 changes: 6 additions & 3 deletions Sources/Chat/Chat+AsyncAwait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,14 @@ public extension Chat {

/// Returns a list of ``User`` identifiers present on the given ``Channel``.
///
/// - Parameter channelId: Unique identifier of the channel where you want to check all present users
/// - Parameters:
/// - channelId: Unique identifier of the channel where you want to check all present users
/// - limit: The number of occupants to fetch per channel. The maximum value is 1000
/// - offset: The offset to return occupancy results from
/// - Returns: A value containing collection of user identifiers
func whoIsPresent(channelId: String) async throws -> [String] {
func whoIsPresent(channelId: String, limit: Int = 1000, offset: Int? = 0) async throws -> [String] {
try await withCheckedThrowingContinuation { continuation in
whoIsPresent(channelId: channelId) {
whoIsPresent(channelId: channelId, limit: limit, offset: offset) {
switch $0 {
case let .success(userIdentifiers):
continuation.resume(returning: userIdentifiers)
Expand Down
4 changes: 4 additions & 0 deletions Sources/Chat/Chat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,15 @@ public protocol Chat: AnyObject {
///
/// - Parameters:
/// - channelId: Unique identifier of the channel where you want to check all present users
/// - limit: The number of occupants to fetch per channel. The maximum value is 1000
/// - offset: The offset to return occupancy results from
/// - completion: The async `Result` of the method call
/// - **Success**: A value containing collection of user identifiers
/// - **Failure**: An `Error` describing the failure
func whoIsPresent(
channelId: String,
limit: Int,
offset: Int?,
completion: ((Swift.Result<[String], Error>) -> Void)?
)

Expand Down
2 changes: 1 addition & 1 deletion Sources/Chat/ChatConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public enum LogLevel {
/// The most verbose logging - print all other types of logs and more
case verbose

func transform() -> PubNubChat.LogLevel {
func transform() -> PubNubChat.LogLevel_ {
switch self {
case .off:
.off
Expand Down
6 changes: 5 additions & 1 deletion Sources/Chat/ChatImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,14 @@ extension ChatImpl: Chat {

public func whoIsPresent(
channelId: String,
limit: Int = 1000,
offset: Int? = 0,
completion: ((Swift.Result<[String], Error>) -> Void)? = nil
) {
chat.whoIsPresent(
channelId: channelId
channelId: channelId,
limit: Int32(limit),
offset: offset?.asKotlinInt
).async(caller: self) { (result: FutureResult<ChatImpl, [String]>) in
switch result.result {
case let .success(ids):
Expand Down
4 changes: 2 additions & 2 deletions Sources/Entities/BaseChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ final class BaseChannel<C: PubNubChat.Channel_, M: PubNubChat.Message>: Channel
)
}

func whoIsPresent(completion: ((Swift.Result<[String], Error>) -> Void)?) {
channel.whoIsPresent().async(caller: self) { (result: FutureResult<BaseChannel, [String]>) in
func whoIsPresent(limit: Int, offset: Int?, completion: ((Swift.Result<[String], Error>) -> Void)?) {
channel.whoIsPresent(limit: Int32(limit), offset: offset?.asKotlinInt).async(caller: self) { (result: FutureResult<BaseChannel, [String]>) in
switch result.result {
case let .success(userIdentifiers):
completion?(.success(userIdentifiers))
Expand Down
7 changes: 5 additions & 2 deletions Sources/Entities/Channel+AsyncAwait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,13 @@ public extension Channel {

/// Returns a list of users present on the ``Channel``.
///
/// - Parameters:
/// - limit: The number of occupants to fetch per channel. The maximum value is 1000
/// - offset: The offset to return occupancy results from
/// - Returns: A collection of strings representing `userId`
func whoIsPresent() async throws -> [String] {
func whoIsPresent(limit: Int = 1000, offset: Int? = 0) async throws -> [String] {
try await withCheckedThrowingContinuation { continuation in
whoIsPresent {
whoIsPresent(limit: limit, offset: offset) {
switch $0 {
case let .success(collection):
continuation.resume(returning: collection)
Expand Down
4 changes: 4 additions & 0 deletions Sources/Entities/Channel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,14 @@ public protocol Channel: CustomStringConvertible {
/// Returns a list of users present on the ``Channel``.
///
/// - Parameters:
/// - limit: The number of occupants to fetch per channel. The maximum value is 1000
/// - offset: The offset to return occupancy results from
/// - completion: The async `Result` of the method call
/// - **Success**: A collection of strings representing `userId`
/// - **Failure**: An `Error` describing the failure
func whoIsPresent(
limit: Int,
offset: Int?,
completion: ((Swift.Result<[String], Error>) -> Void)?
)

Expand Down
7 changes: 5 additions & 2 deletions Sources/Entities/ChannelGroup+AsyncAwait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,13 @@ public extension ChannelGroup {

/// Returns a collection of users currently present in any channel within the given ``ChannelGroup``.
///
/// - Parameters:
/// - limit: The number of occupants to fetch per channel. The maximum value is 1000
/// - offset: The offset to return occupancy results from
/// - Returns: A `Dictionary` where the key is a ``Channel`` identifier and the value is an array of present user identifiers
func whoIsPresent() async throws -> [String: [String]] {
func whoIsPresent(limit: Int = 1000, offset: Int? = 0) async throws -> [String: [String]] {
try await withCheckedThrowingContinuation { continuation in
whoIsPresent {
whoIsPresent(limit: limit, offset: offset) {
switch $0 {
case let .success(result):
continuation.resume(returning: result)
Expand Down
4 changes: 3 additions & 1 deletion Sources/Entities/ChannelGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@ public protocol ChannelGroup {
/// Returns a collection of users currently present in any channel within the given ``ChannelGroup``.
///
/// - Parameters:
/// - limit: The number of occupants to fetch per channel. The maximum value is 1000
/// - offset: The offset to return occupancy results from
/// - completion: The async `Result` of the method call
/// - **Success**: A `Dictionary` where the key is a ``Channel`` identifier and the value is an array of present user identifiers
/// - **Failure**: An `Error` describing the failure
func whoIsPresent(completion: ((Swift.Result<[String: [String]], Error>) -> Void)?)
func whoIsPresent(limit: Int, offset: Int?, completion: ((Swift.Result<[String: [String]], Error>) -> Void)?)

/// Enables real-time tracking of users connecting to or disconnecting from the given ``ChannelGroup``.
///
Expand Down
11 changes: 9 additions & 2 deletions Sources/Entities/ChannelGroupImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,15 @@ public class ChannelGroupImpl: ChannelGroup {
}
}

public func whoIsPresent(completion: ((Swift.Result<[String: [String]], Error>) -> Void)?) {
channelGroup.whoIsPresent().async(caller: self) { (result: FutureResult<ChannelGroupImpl, [String: [String]]>) in
public func whoIsPresent(
limit: Int = 1000,
offset: Int? = 0,
completion: ((Swift.Result<[String: [String]], Error>) -> Void)?
) {
channelGroup.whoIsPresent(
limit: Int32(limit),
offset: offset?.asKotlinInt
).async(caller: self) { (result: FutureResult<ChannelGroupImpl, [String: [String]]>) in
switch result.result {
case let .success(ids):
completion?(.success(ids))
Expand Down
4 changes: 3 additions & 1 deletion Sources/Entities/ChannelImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,10 @@ extension ChannelImpl: Channel {
)
}

public func whoIsPresent(completion: ((Swift.Result<[String], Error>) -> Void)? = nil) {
public func whoIsPresent(limit: Int = 1000, offset: Int? = 0, completion: ((Swift.Result<[String], Error>) -> Void)? = nil) {
target.whoIsPresent(
limit: limit,
offset: offset,
completion: completion
)
}
Expand Down
4 changes: 3 additions & 1 deletion Sources/Entities/ThreadChannelImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,10 @@ extension ThreadChannelImpl: ThreadChannel {
)
}

public func whoIsPresent(completion: ((Swift.Result<[String], Error>) -> Void)? = nil) {
public func whoIsPresent(limit: Int = 1000, offset: Int? = 0, completion: ((Swift.Result<[String], Error>) -> Void)? = nil) {
target.whoIsPresent(
limit: limit,
offset: offset,
completion: completion
)
}
Expand Down
2 changes: 0 additions & 2 deletions Sources/Extensions/PubNub.PushService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ extension PubNub.PushService {
.fcm
case .apns:
.apns
case .mpns:
.mpns
}
}
}
2 changes: 0 additions & 2 deletions Sources/Extensions/PubNubChat.PNPushType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ extension PubNubChat.PNPushType {
switch self {
case .apns:
.apns
case .mpns:
.mpns
case .gcm:
.fcm
case .apns2:
Expand Down
2 changes: 1 addition & 1 deletion Sources/Miscellaneous/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@

import Foundation

let pubNubSwiftChatSDKVersion: String = "0.33.0"
let pubNubSwiftChatSDKVersion: String = "0.34.0"
20 changes: 20 additions & 0 deletions Tests/AsyncAwait/ChannelAsyncIntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,26 @@ class ChannelAsyncIntegrationTests: BaseAsyncIntegrationTestCase {
XCTAssertEqual(whoIsPresent.first, chat.currentUser.id)
}

func testChannelAsync_WhoIsPresentWithLimitAndOffset() async throws {
// Keeps a strong reference to the returned AsyncStream to prevent it from being deallocated. If this object is not retained,
// the AsyncStream will be deallocated, which would cause the behavior being tested to fail.
let joinResult = try await channel.join()
debugPrint(joinResult)

try await Task.sleep(nanoseconds: 4_000_000_000)

let whoIsPresentWithLimit = try await channel.whoIsPresent(limit: 10)
XCTAssertEqual(whoIsPresentWithLimit.count, 1)
XCTAssertEqual(whoIsPresentWithLimit.first, chat.currentUser.id)

let whoIsPresentWithOffset = try await channel.whoIsPresent(limit: 10, offset: 1)
XCTAssertTrue(whoIsPresentWithOffset.isEmpty)

let whoIsPresentWithZeroOffset = try await channel.whoIsPresent(limit: 10, offset: 0)
XCTAssertEqual(whoIsPresentWithZeroOffset.count, 1)
XCTAssertEqual(whoIsPresentWithZeroOffset.first, chat.currentUser.id)
}

func testChannelAsync_IsPresent() async throws {
// Keeps a strong reference to the returned AsyncStream to prevent it from being deallocated. If this object is not retained,
// the AsyncStream will be deallocated, which would cause the behavior being tested to fail.
Expand Down