Skip to content

Commit 7512be9

Browse files
authored
refactor(realtime): general realtime improvements (#426)
1 parent 083c6c3 commit 7512be9

File tree

9 files changed

+81
-8
lines changed

9 files changed

+81
-8
lines changed

Examples/Examples/AnyJSONView.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ struct AnyJSONView: View {
3333
}
3434
}
3535
}
36-
3736
case let .object(object):
3837
let elements = Array(object).sorted(by: { $0.key < $1.key })
3938
ForEach(elements, id: \.key) { element in

Examples/UserManagement/AppView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct AppView: View {
1919
}
2020
}
2121
.task {
22-
for await state in await supabase.auth.authStateChanges {
22+
for await state in supabase.auth.authStateChanges {
2323
if [.initialSession, .signedIn, .signedOut].contains(state.event) {
2424
isAuthenticated = state.session != nil
2525
}

Examples/UserManagement/ProfileView.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ struct ProfileView: View {
101101
do {
102102
let currentUser = try await supabase.auth.session.user
103103

104-
let profile: Profile = try await supabase.database
105-
.from("profiles")
104+
let profile: Profile = try await supabase.from("profiles")
106105
.select()
107106
.eq("id", value: currentUser.id)
108107
.single()
@@ -138,7 +137,7 @@ struct ProfileView: View {
138137
avatarURL: imageURL
139138
)
140139

141-
try await supabase.database
140+
try await supabase
142141
.from("profiles")
143142
.update(updatedProfile)
144143
.eq("id", value: currentUser.id)

Sources/Realtime/V2/CallbackManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import ConcurrencyExtras
99
import Foundation
1010
import Helpers
1111

12-
final class CallbackManager: @unchecked Sendable {
12+
final class CallbackManager: Sendable {
1313
struct MutableState {
1414
var id = 0
1515
var serverChanges: [PostgresJoinConfig] = []

Sources/Realtime/V2/RealtimeChannelV2.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,18 @@ public final class RealtimeChannelV2: Sendable {
176176
)
177177
}
178178

179+
/// Send a broadcast message with `event` and a `Codable` payload.
180+
/// - Parameters:
181+
/// - event: Broadcast message event.
182+
/// - message: Message payload.
179183
public func broadcast(event: String, message: some Codable) async throws {
180184
try await broadcast(event: event, message: JSONObject(message))
181185
}
182186

187+
/// Send a broadcast message with `event` and a raw `JSON` payload.
188+
/// - Parameters:
189+
/// - event: Broadcast message event.
190+
/// - message: Message payload.
183191
public func broadcast(event: String, message: JSONObject) async {
184192
assert(
185193
status == .subscribed,

Sources/Realtime/V2/RealtimeMessageV2.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,15 @@ public struct RealtimeMessageV2: Hashable, Codable, Sendable {
2323
self.payload = payload
2424
}
2525

26+
var status: PushStatus? {
27+
payload["status"]
28+
.flatMap(\.stringValue)
29+
.flatMap(PushStatus.init(rawValue:))
30+
}
31+
2632
public var eventType: EventType? {
2733
switch event {
28-
case ChannelEvent.system where payload["status"]?.stringValue == "ok": .system
34+
case ChannelEvent.system where status == .ok: .system
2935
case ChannelEvent.postgresChanges:
3036
.postgresChanges
3137
case ChannelEvent.broadcast:

Sources/Realtime/V2/WebSocketClient.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ final class WebSocket: NSObject, URLSessionWebSocketDelegate, WebSocketClient, @
9696

9797
case .data:
9898
fallthrough
99+
99100
default:
100101
throw RealtimeError("Unsupported message type.")
101102
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// RealtimeMessageV2Tests.swift
3+
//
4+
//
5+
// Created by Guilherme Souza on 26/06/24.
6+
//
7+
8+
@testable import Realtime
9+
import XCTest
10+
11+
final class RealtimeMessageV2Tests: XCTestCase {
12+
func testStatus() {
13+
var message = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "heartbeat", event: "event", payload: ["status": "ok"])
14+
XCTAssertEqual(message.status, .ok)
15+
16+
message = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "heartbeat", event: "event", payload: ["status": "timeout"])
17+
XCTAssertEqual(message.status, .timeout)
18+
19+
message = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "heartbeat", event: "event", payload: ["status": "error"])
20+
XCTAssertEqual(message.status, .error)
21+
22+
message = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "heartbeat", event: "event", payload: ["status": "invalid"])
23+
XCTAssertNil(message.status)
24+
}
25+
26+
func testEventType() {
27+
let payloadWithTokenExpiredMessage: JSONObject = ["message": "access token has expired"]
28+
let payloadWithStatusOK: JSONObject = ["status": "ok"]
29+
let payloadWithNoStatus: JSONObject = [:]
30+
31+
let systemEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.system, payload: payloadWithStatusOK)
32+
let postgresChangesEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.postgresChanges, payload: payloadWithNoStatus)
33+
let tokenExpiredEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.system, payload: payloadWithTokenExpiredMessage)
34+
35+
XCTAssertEqual(systemEventMessage.eventType, .system)
36+
XCTAssertEqual(postgresChangesEventMessage.eventType, .postgresChanges)
37+
XCTAssertEqual(tokenExpiredEventMessage.eventType, .tokenExpired)
38+
39+
let broadcastEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.broadcast, payload: payloadWithNoStatus)
40+
XCTAssertEqual(broadcastEventMessage.eventType, .broadcast)
41+
42+
let closeEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.close, payload: payloadWithNoStatus)
43+
XCTAssertEqual(closeEventMessage.eventType, .close)
44+
45+
let errorEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.error, payload: payloadWithNoStatus)
46+
XCTAssertEqual(errorEventMessage.eventType, .error)
47+
48+
let presenceDiffEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.presenceDiff, payload: payloadWithNoStatus)
49+
XCTAssertEqual(presenceDiffEventMessage.eventType, .presenceDiff)
50+
51+
let presenceStateEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.presenceState, payload: payloadWithNoStatus)
52+
XCTAssertEqual(presenceStateEventMessage.eventType, .presenceState)
53+
54+
let replyEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.reply, payload: payloadWithNoStatus)
55+
XCTAssertEqual(replyEventMessage.eventType, .reply)
56+
57+
let unknownEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: "unknown_event", payload: payloadWithNoStatus)
58+
XCTAssertNil(unknownEventMessage.eventType)
59+
}
60+
}

Tests/RealtimeTests/RealtimeTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ final class RealtimeTests: XCTestCase {
3737

3838
override func tearDown() {
3939
sut.disconnect()
40-
40+
4141
super.tearDown()
4242
}
4343

0 commit comments

Comments
 (0)