Skip to content

Instantly share code, notes, and snippets.

@justinpawela
Forked from networkextension/actor_dl_imge.swift
Created February 29, 2024 02:51
Show Gist options
  • Save justinpawela/826c98c0f17c891ac8564175a9d13681 to your computer and use it in GitHub Desktop.
Save justinpawela/826c98c0f17c891ac8564175a9d13681 to your computer and use it in GitHub Desktop.
actor async/await download imge Swift 5.5
extension UIImage {
@available(iOS 15, *)
var thumbnail: UIImage? {
get async {
let size = CGSize(width: 80, height: 40)
return await self.byPreparingThumbnail(ofSize: size)
}
}
}
enum FetchError:Error{
case badID
case badImage
}
actor ImageDownloader {
private enum CacheEntry {
case inProgress(Task.Handle<Image, Error>)
case ready(Image)
}
private var cache: [URL: CacheEntry] = [:]
func image(from url: URL) async throws -> Image? {
if let cached = cache[url] {
switch cached {
case .ready(let image):
return image
case .inProgress(let handle):
return try await handle.get()
}
}
let handle = async {
try await downloadImage(from: url)
}
cache[url] = .inProgress(handle)
do {
let image = try await handle.get()
cache[url] = .ready(image)
return image
} catch {
cache[url] = nil
throw error
}
}
//URL.init(string:"https://www.apple.com/v/home/hc/images/overview/ios15_logo__cnpdxsz7otzm_large_2x.png")!)
func downloadImage(from url:URL) async throws -> Image{
let request = URLRequest.init(url:url)
let (data, response) = try await URLSession.shared.data(for: request)
guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw FetchError.badID }
let maybeImage = UIImage(data: data)
guard let thumbnail = await maybeImage?.thumbnail else { throw FetchError.badImage }
return Image(uiImage: thumbnail)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment