Could you elaborate a bit more, why you need the extra closure? Naively, since I am not familiar with this API, I would‘ve just used withTaskCancellationHandler
like this:
extension PHImageManager {
func requestImage(
for asset: PHAsset,
targetSize: CGSize,
contentMode: PHImageContentMode,
options: PHImageRequestOptions?
) async throws -> UIImage {
let requestId = LockIsolated<PHImageRequestID?>(nil)
return try await withTaskCancellationHandler {
return try await withUnsafeThrowingContinuation { continuation in
let newRequestId = requestImage(for: asset, targetSize: targetSize, contentMode: contentMode, options: options) { image, _ in
if let image {
continuation.resume(returning: image)
} else {
continuation.resume(throwing: CancellationError())
}
}
requestId.setValue(newRequestId)
}
} onCancel: {
requestId.withValue { requestId in
if let requestId {
cancelImageRequest(requestId)
}
}
}
}
}
LockIsolated
is a helper from swift-concurrency-extras
but I‘d imagine you could use Mutex
instead, when it is released.
Edit: Please do not use this snippet, it is just for demonstration purposes. It will crash in some conditions because the requestImage
closure can be called multiple times.