Skip to content

Commit efa2b7c

Browse files
Merge pull request #1061 from liveview-native/await-disconnect
Wait for disconnect to finish
2 parents 575a0e2 + 454ea89 commit efa2b7c

File tree

2 files changed

+29
-28
lines changed

2 files changed

+29
-28
lines changed

Sources/LiveViewNative/Coordinators/LiveSessionCoordinator.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
8383
let last = next.last ?? .init(url: self.url, coordinator: self.rootCoordinator)
8484
if last.coordinator.url != last.url {
8585
last.coordinator.url = last.url
86-
print("NAVIGATE BACK")
8786
Task { @MainActor in
8887
try await last.coordinator.connect(domValues: self.domValues, redirect: true)
8988
}
@@ -166,10 +165,10 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
166165
}
167166
}
168167

169-
private func disconnect() {
170-
rootCoordinator.disconnect()
168+
private func disconnect() async {
169+
await rootCoordinator.disconnect()
171170
for entry in self.navigationPath {
172-
entry.coordinator.disconnect()
171+
await entry.coordinator.disconnect()
173172
}
174173
self.navigationPath.removeAll()
175174
self.socket?.disconnect()
@@ -183,7 +182,7 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
183182
///
184183
/// This can be used to force the LiveView to reset, for example after an unrecoverable error occurs.
185184
public func reconnect() async {
186-
self.disconnect()
185+
await self.disconnect()
187186
await self.connect()
188187
}
189188

@@ -351,7 +350,7 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
351350
case .replaceTop:
352351
let coordinator = (navigationPath.last?.coordinator ?? rootCoordinator)!
353352
coordinator.url = redirect.to
354-
coordinator.disconnect()
353+
await coordinator.disconnect()
355354
let entry = LiveNavigationEntry(url: redirect.to, coordinator: coordinator)
356355
switch redirect.kind {
357356
case .push:

Sources/LiveViewNative/Coordinators/LiveViewCoordinator.swift

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,7 @@ public class LiveViewCoordinator<R: RootRegistry>: ObservableObject {
207207
}
208208

209209
func connect(domValues: LiveSessionCoordinator<R>.DOMValues, redirect: Bool) async throws {
210-
print("CONNECTING \(self.url)")
211-
self.disconnect()
210+
await self.disconnect()
212211

213212
self.internalState = .connecting
214213

@@ -264,11 +263,16 @@ public class LiveViewCoordinator<R: RootRegistry>: ObservableObject {
264263
self.internalState = .connected
265264
}
266265

267-
func disconnect() {
266+
func disconnect() async {
268267
if let channel,
269-
channel.isJoined
268+
!channel.isClosed
270269
{
271-
channel.leave()
270+
await withCheckedContinuation { continuation in
271+
channel.onClose { _ in
272+
continuation.resume()
273+
}
274+
channel.leave()
275+
}
272276
}
273277
channel = nil
274278
self.internalState = .notConnected
@@ -300,27 +304,25 @@ public class LiveViewCoordinator<R: RootRegistry>: ObservableObject {
300304
continuation.resume(returning: .rendered(renderedPayload))
301305
}
302306
.receive("error") { [weak self, weak channel] message in
303-
guard let channel else {
304-
continuation.resume(throwing: LiveConnectionError.viewCoordinatorReleased)
305-
return
306-
}
307-
// TODO: reconsider this behavior, web tries to automatically rejoin, and we do to when an error is encountered after a successful join
308-
// leave the channel, otherwise the it'll continue retrying indefinitely
309-
// we want to control the retry behavior ourselves, so just leave the channel
310-
if channel.isJoined {
311-
channel.leave()
312-
}
313-
314-
guard let self = self else {
307+
guard channel != nil else {
315308
continuation.resume(throwing: LiveConnectionError.viewCoordinatorReleased)
316309
return
317310
}
318311

319-
if self.session.configuration.navigationMode.permitsRedirects,
320-
let redirect = (message.payload["live_redirect"] as? Payload).flatMap({ LiveRedirect(from: $0, relativeTo: self.url) }) {
321-
continuation.resume(returning: .redirect(redirect))
322-
} else {
323-
continuation.resume(throwing: LiveConnectionError.joinError(message))
312+
Task { [weak self] in
313+
guard let self else {
314+
continuation.resume(throwing: LiveConnectionError.viewCoordinatorReleased)
315+
return
316+
}
317+
318+
await self.disconnect()
319+
320+
if self.session.configuration.navigationMode.permitsRedirects,
321+
let redirect = (message.payload["live_redirect"] as? Payload).flatMap({ LiveRedirect(from: $0, relativeTo: self.url) }) {
322+
continuation.resume(returning: .redirect(redirect))
323+
} else {
324+
continuation.resume(throwing: LiveConnectionError.joinError(message))
325+
}
324326
}
325327
}
326328
}

0 commit comments

Comments
 (0)