Skip to content

Commit

Permalink
Merge pull request #1119 from liveview-native/background-crash
Browse files Browse the repository at this point in the history
Use `AsyncThrowingStream` to handle join replies
  • Loading branch information
supernintendo authored Aug 30, 2023
2 parents 805df23 + 712250f commit 2a3df0b
Showing 1 changed file with 31 additions and 19 deletions.
50 changes: 31 additions & 19 deletions Sources/LiveViewNative/Coordinators/LiveViewCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -278,17 +278,23 @@ public class LiveViewCoordinator<R: RootRegistry>: ObservableObject {
}
}

let joinResult = try await join(channel: channel)

switch joinResult {
case .rendered(let payload):
self.handleJoinPayload(renderedPayload: payload)
case .redirect(let liveRedirect):
self.url = liveRedirect.to
try await self.connect(domValues: domValues, redirect: true)
let joinTask = Task {
for try await joinResult in join(channel: channel) {
switch joinResult {
case .rendered(let payload):
self.handleJoinPayload(renderedPayload: payload)
case .redirect(let liveRedirect):
self.url = liveRedirect.to
try await self.connect(domValues: domValues, redirect: true)
}

self.internalState = .connected
}
}

self.internalState = .connected
channel.onClose { _ in
joinTask.cancel()
}
}

func disconnect() async {
Expand All @@ -312,47 +318,53 @@ public class LiveViewCoordinator<R: RootRegistry>: ObservableObject {
case redirect(LiveRedirect)
}

private func join(channel: Channel) async throws -> JoinResult {
try await withCheckedThrowingContinuation { continuation in
channel.join()
private func join(channel: Channel) -> AsyncThrowingStream<JoinResult, Error> {
return AsyncThrowingStream<JoinResult, Error> { [weak channel] (continuation: AsyncThrowingStream<JoinResult, Error>.Continuation) -> Void in
channel?.join()
.receive("ok") { [weak self, weak channel] message in
guard let channel else {
continuation.resume(throwing: LiveConnectionError.viewCoordinatorReleased)
continuation.finish(throwing: LiveConnectionError.viewCoordinatorReleased)
return
}
guard self != nil else {
// leave the channel so we don't get any more messages/automatic rejoins
if channel.isJoined {
channel.leave()
}
continuation.resume(throwing: LiveConnectionError.viewCoordinatorReleased)
continuation.finish(throwing: LiveConnectionError.viewCoordinatorReleased)
return
}
let renderedPayload = (message.payload["rendered"] as! Payload)
continuation.resume(returning: .rendered(renderedPayload))
continuation.yield(.rendered(renderedPayload))
}
.receive("error") { [weak self, weak channel] message in
guard channel != nil else {
continuation.resume(throwing: LiveConnectionError.viewCoordinatorReleased)
continuation.finish(throwing: LiveConnectionError.viewCoordinatorReleased)
return
}

Task { [weak self] in
guard let self else {
continuation.resume(throwing: LiveConnectionError.viewCoordinatorReleased)
continuation.finish(throwing: LiveConnectionError.viewCoordinatorReleased)
return
}

await self.disconnect()

if self.session.configuration.navigationMode.permitsRedirects,
let redirect = (message.payload["live_redirect"] as? Payload).flatMap({ LiveRedirect(from: $0, relativeTo: self.url) }) {
continuation.resume(returning: .redirect(redirect))
continuation.yield(.redirect(redirect))
} else {
continuation.resume(throwing: LiveConnectionError.joinError(message))
continuation.finish(throwing: LiveConnectionError.joinError(message))
}
}
}
channel?.onClose { _ in
continuation.finish()
}
continuation.onTermination = { [weak channel] termination in
channel?.leave()
}
}
}

Expand Down

0 comments on commit 2a3df0b

Please sign in to comment.