Reputation: 1110
I'm trying to implement a function which returns an AsyncStream of BlurredImage objects. The functions relies on another function sourceImages(), which itself is an AsyncStream.
I get this error on line 2 of my snippet:
Cannot pass function of type '(AsyncStream<BlurredImage>.Continuation) async -> Void' to parameter expecting synchronous function type
What's the correct way to implement this?
func blurredFaces() -> AsyncStream<BlurredImage> {
return AsyncStream<BlurredImage> { continuation in
for await image in sourceImages() {
blurrImage(image) { blurredImage in
continuation.yield(blurredImage)
}
}
continuation.finish()
}
}
func sourceImages() -> AsyncStream<SourceImage> {
...
}
I'm on Xcode 13.4.1
Upvotes: 1
Views: 1363
Reputation: 457
AsyncStream.init
expects an input of type (AsyncStream<BlurredImage>.Continuation) → Void
, which is not async.
But you can wrap its body in a Task
to do async operations.
return AsyncStream<BlurredImage> { continuation in
Task {
for await image in sourceImages() {
blurrImage(image) { blurredImage in
continuation.yield(blurredImage)
}
}
continuation.finish()
}
}
Or as @Sweeper suggested, you can use map
. Based on your blurredFaces
return type signature, you want to map AsyncStream<SourceImage>
(result of sourceImages
) to AsyncStream<BlurredImage>
.
In case for some reason you want to keep its return type as that, I haven't found a built-in direct map from an AsyncStream<T1>
to an AsyncStream<T2>
, so I posted this related SO question. In this answer, I shared the AsyncStream
extension that I created for this use case. I am still waiting for feedbacks for this solution.
Upvotes: 3
Reputation: 271420
You seem to be doing an mapping operation here. In that case, you can use map
and return an AsyncMapSequence
:
func blurredFaces() -> AsyncMapSequence<AsyncStream<SourceImage>, BlurredImage> {
sourceImages().map { image in
await withCheckedContinuation { continuation in
blurrImage(image) { blurred in
continuation.resume(returning: blurred)
}
}
}
}
If you can make blurrImage
async
, then this can be even shorter:
func blurredFaces() -> AsyncMapSequence<AsyncStream<SourceImage>, BlurredImage> {
// you can even inline this, and get rid of blurredFaces
sourceImages().map(blurrImage)
}
Upvotes: 2