diff --git a/Sources/AblyChat/Presence.swift b/Sources/AblyChat/Presence.swift index 8d269245..148b571d 100644 --- a/Sources/AblyChat/Presence.swift +++ b/Sources/AblyChat/Presence.swift @@ -5,7 +5,7 @@ public typealias PresenceData = any Sendable public protocol Presence: AnyObject, Sendable, EmitsDiscontinuities { func get() async throws -> [PresenceMember] - func get(params: ARTRealtimePresenceQuery?) async throws -> [PresenceMember] + func get(params: PresenceQuery?) async throws -> [PresenceMember] func isUserPresent(clientID: String) async throws -> Bool func enter() async throws func enter(data: PresenceData) async throws @@ -61,3 +61,24 @@ public struct PresenceEvent: Sendable { self.data = data } } + +// This is a Sendable equivalent of ably-cocoa’s ARTRealtimePresenceQuery type. +// +// Originally, ``Presence.get(params:)`` accepted an ARTRealtimePresenceQuery object, but I’ve changed it to accept this type, because else when you try and write an actor that implements ``Presence``, you get a compiler error like "Non-sendable type 'ARTRealtimePresenceQuery' in parameter of the protocol requirement satisfied by actor-isolated instance method 'get(params:)' cannot cross actor boundary; this is an error in the Swift 6 language mode". +// +// Now, based on my limited understanding, you _should_ be able to send non-Sendable values from one isolation domain to another (the purpose of the "region-based isolation" and "`sending` parameters" features added in Swift 6), but to get this to work I had to mark ``Presence`` as requiring conformance to the `Actor` protocol, and since I didn’t understand _why_ I had to do that, I didn’t want to put it in the public API. +// +// So, for now, let’s just accept this copy (which I don’t think is a big problem anyway); we can always revisit it with more Swift concurrency knowledge in the future. Created https://github.com/ably-labs/ably-chat-swift/issues/64 to revisit. +public struct PresenceQuery: Sendable { + public var limit = 100 + public var clientID: String? + public var connectionID: String? + public var waitForSync = true + + internal init(limit: Int = 100, clientID: String? = nil, connectionID: String? = nil, waitForSync: Bool = true) { + self.limit = limit + self.clientID = clientID + self.connectionID = connectionID + self.waitForSync = waitForSync + } +}