Last active
September 26, 2024 10:55
-
-
Save sergdort/d5d3cc28cc9df889ab6b1410d16581ad to your computer and use it in GitHub Desktop.
Bridge between async await and Publisher.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@available(iOS 15.0, *) | |
struct TaskPublisher<Output>: Publisher{ | |
typealias Failure = Never | |
let work: () async -> Output | |
init(work: @escaping () async -> Output) { | |
self.work = work | |
} | |
func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input { | |
let subscription = TaskSubscription(work: work, subscriber: subscriber) | |
subscriber.receive(subscription: subscription) | |
subscription.start() | |
} | |
final class TaskSubscription<Output, Downstream: Subscriber>: Combine.Subscription where Downstream.Input == Output, Downstream.Failure == Never { | |
private var handle: Task.Handle<Output, Never>? | |
private let work: () async -> Output | |
private let subscriber: Downstream | |
init(work: @escaping () async -> Output, subscriber: Downstream) { | |
self.work = work | |
self.subscriber = subscriber | |
} | |
func start() { | |
self.handle = async { [subscriber, work] in | |
let result = await work() | |
_ = subscriber.receive(result) | |
subscriber.receive(completion: .finished) | |
return result | |
} | |
} | |
func request(_ demand: Subscribers.Demand) {} | |
func cancel() { | |
handle?.cancel() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment