diff --git a/README.md b/README.md index 1f5384b..f21455b 100644 --- a/README.md +++ b/README.md @@ -96,11 +96,35 @@ allUserId99Changes.subscribe() allUserId99Changes.unsubscribe() allUserId99Changes.off(.all) ``` +### Broadcast + +* Listen for `broadcast` messages: + +```swift +let channel = client.channel(.table("channel_id", schema: "someChannel"), options: .init(presenceKey: "user_uuid")) +channel.on(.broadcast) { message in + let payload = message.payload["payload"] + let event = message.payload["event"] + let type = message.payload["type"] + print(type, event, payload) +} + +channel.join() +``` + +* Send `broadcast` messages: + +```swift +let channel = client.channel(.table("channel_id", schema: "someChannel"), options: .init(presenceKey: "user_uuid")) +channel.join() + +channel.broadcast(event: "my_event", payload: ["hello": "world"]) +``` ### Presence Presence can be used to share state between clients. -* Listen to presence `sync` events: +* Listen to presence `sync` events to track state changes: ```swift let channel = client.channel(.table("channel_id", schema: "someChannel"), options: .init(presenceKey: "user_uuid")) @@ -114,6 +138,25 @@ channel.join() // ... ``` +* Track presence state changes: + +```swift +let channel = client.channel(.table("channel_id", schema: "someChannel"), options: .init(presenceKey: "user_uuid")) +channel.join() + +channel.track(payload: [ + ["hello": "world] +]) +``` + +* Remove tracked presence state changes: + +```swift +let channel = client.channel(.table("channel_id", schema: "someChannel"), options: .init(presenceKey: "user_uuid")) +channel.join() + +channel.untrack() +``` ## Credits - https://github.com/supabase/realtime-js diff --git a/Sources/Realtime/Channel.swift b/Sources/Realtime/Channel.swift index 38345fd..700885f 100644 --- a/Sources/Realtime/Channel.swift +++ b/Sources/Realtime/Channel.swift @@ -694,3 +694,44 @@ extension Channel { return state == .leaving } } + +// ---------------------------------------------------------------------- + +// MARK: - Broadcast API + +// ---------------------------------------------------------------------- +extension Channel { + @discardableResult + public func broadcast(event: String, payload: Payload) -> Push { + self.push(.broadcast, payload: [ + "type": "broadcast", + "event": event, + "payload": payload + ]) + } +} +// ---------------------------------------------------------------------- + +// MARK: - Presence API + +// ---------------------------------------------------------------------- + +extension Channel { + @discardableResult + public func track(payload: Payload) -> Push { + self.push(.presence, payload: [ + "type": "presence", + "event": "track", + "payload": payload + ]) + } + + @discardableResult + public func untrack() -> Push { + self.push(.presence, payload: [ + "type": "presence", + "event": "untrack" + ]) + } + +} diff --git a/Sources/Realtime/Defaults.swift b/Sources/Realtime/Defaults.swift index e412c7c..c7cd7cc 100644 --- a/Sources/Realtime/Defaults.swift +++ b/Sources/Realtime/Defaults.swift @@ -104,7 +104,11 @@ public enum ChannelEvent: RawRepresentable { case channelReply(String) - case presence(Presence) + case broadcast + + case presence + case presenceState + case presenceDiff public var rawValue: String { switch self { @@ -121,7 +125,12 @@ public enum ChannelEvent: RawRepresentable { case .delete: return "delete" case let .channelReply(reference): return "chan_reply_\(reference)" - case let .presence(presence): return "presence_\(presence.rawValue)" + + case .broadcast: return "broadcast" + + case .presence: return "presence" + case .presenceState: return "presence_state" + case .presenceDiff: return "presence_diff" } } @@ -137,8 +146,10 @@ public enum ChannelEvent: RawRepresentable { case "insert": self = .insert case "update": self = .update case "delete": self = .delete - case "presence_state": self = .presence(.state) - case "presence_diff": self = .presence(.diff) + case "broadcast": self = .broadcast + case "presence": self = .presence + case "presence_state": self = .presenceState + case "presence_diff": self = .presenceDiff default: return nil } } diff --git a/Sources/Realtime/Presence.swift b/Sources/Realtime/Presence.swift index 4ae85c9..412513e 100644 --- a/Sources/Realtime/Presence.swift +++ b/Sources/Realtime/Presence.swift @@ -108,8 +108,8 @@ public final class Presence { /// Default set of Options used when creating Presence. Uses the /// phoenix events "presence_state" and "presence_diff" public static let defaults = Options(events: [ - .state: .presence(.state), - .diff: .presence(.diff), + .state: .presenceState, + .diff: .presenceState, ]) public init(events: [Events: ChannelEvent]) {