Skip to content

Instantly share code, notes, and snippets.

@pofat
Created August 16, 2022 08:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pofat/c23826d683b4dac73bcca738944b07b2 to your computer and use it in GitHub Desktop.
Save pofat/c23826d683b4dac73bcca738944b07b2 to your computer and use it in GitHub Desktop.
Delegate with AsyncStream
protocol FooDelegate: AnyObject {
func didReceive(value: Int)
func didOpen()
func didClose()
}
class Foo {
weak var delegate: FooDelegate?
func open() {
delegate?.didOpen()
}
func close() {
delegate?.didClose()
}
func send(value: Int) {
delegate?.didReceive(value: value)
}
}
let singleton = Foo()
struct FooClient {
enum Action {
case didOpen, didClose
case didReceive(Int)
}
var create: (AnyHashable) -> AsyncStream<Action>
}
private class Delegate: FooDelegate {
var open: () -> Void
var close: () -> Void
var receive: (Int) -> Void
init(open: @escaping () -> Void, close: @escaping () -> Void, receive: @escaping (Int) -> Void) {
self.open = open
self.close = close
self.receive = receive
}
func didOpen() {
open()
}
func didClose() {
close()
}
func didReceive(value: Int) {
receive(value)
}
}
extension FooClient {
static var app = FooClient { id in
return AsyncStream { continuation in
let delegate = Delegate {
continuation.yield(.didOpen)
} close: {
continuation.yield(.didClose)
} receive: { value in
continuation.yield(.didReceive(value))
}
continuation.onTermination = { @Sendable _ in
print("terminated")
}
singleton.delegate = delegate
}
}
}
func getDelegate() async {
let stream = FooClient.app.create(UUID())
for await action in stream {
switch action {
case .didOpen:
print("open")
case .didClose:
print("close")
case .didReceive(let value):
print("receive \(value)")
}
}
print("stream ended")
}
print("begin task")
Task {
await getDelegate()
}
singleton.open()
singleton.send(value: 1)
singleton.send(value: 3)
singleton.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment