Based on the current structured concurrency pitch, I would expect this to be written as follows, no continuation-specific cancellation functionality needed:
func download(url: URL) async throws -> Data? {
var urlSessionTask: URLSessionTask?
return try Task.withCancellationHandler { urlSessionTask?.cancel() }
operation: {
return try await withUnsafeThrowingContinuation { continuation in
urlSessionTask = URLSession.shared.dataTask(with: url) { data, _, error in
if let error = error {
// Ideally translate NSURLErrorCancelled to CancellationError here
continuation.resume(throwing: error)
} else {
continuation.resume(returning: data)
}
}
urlSessionTask?.resume()
}
}
}