Post

Replies

Boosts

Views

Activity

Reply to Associated Code?
Just slightly tweaking @mayoff's answer which seems sensible to me (accounting for the deprecations): struct Image {     let url: URL } actor ImageDownloader {     private var cache = [URL: Task<Image, Error>]()     func image(for url: URL) async throws -> Image {         if let imageTask = cache[url] {             switch await imageTask.result {             case .success(let image):                 return image             case .failure:                 cache[url] = nil             }         }         let imageTask = Task {             try await downloadImage(url: url)         }         cache[url] = imageTask         switch await imageTask.result {         case .success(let image):             return image         case .failure(let error):             cache[url] = nil             throw error         }     }     private func downloadImage(url: URL) async throws -> Image {         print("Downloading image - \(url.absoluteString)")         try await Task.sleep(nanoseconds: 2 * 1_000_000_000)         return Image(url: url)     } } And you can test this using: let imageDownloader = ImageDownloader() async let image1 = try imageDownloader.image(for: URL(string: "https://test.com")!) async let image2 = try imageDownloader.image(for: URL(string: "https://test.com")!) async let image3 = try imageDownloader.image(for: URL(string: "https://test.com")!) async let anotherImage = try imageDownloader.image(for: URL(string: "https://another.test.com")!) print(try await image1.url.absoluteString) print(try await image2.url.absoluteString) print(try await image3.url.absoluteString) print(try await anotherImage.url.absoluteString) Which should give: Downloading image - https://test.com Downloading image - https://another.test.com https://test.com https://test.com https://test.com https://another.test.com Which shows only two calls to downloadImage(url:) were actually made.
Jan ’22