35 lines
910 B
Swift
35 lines
910 B
Swift
import Foundation
|
|
import UIKit
|
|
|
|
protocol ImageCacheProtocol {
|
|
func image(for url: URL) async throws -> UIImage
|
|
}
|
|
|
|
final class ImageCache: ImageCacheProtocol {
|
|
static let shared = ImageCache()
|
|
|
|
private let cache = NSCache<NSURL, UIImage>()
|
|
private let session: URLSession
|
|
|
|
init(session: URLSession = .shared) {
|
|
self.session = session
|
|
cache.countLimit = 200
|
|
}
|
|
|
|
func image(for url: URL) async throws -> UIImage {
|
|
if let existing = cache.object(forKey: url as NSURL) {
|
|
return existing
|
|
}
|
|
|
|
let request = URLRequest(url: url, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 20)
|
|
let (data, _) = try await session.data(for: request)
|
|
|
|
guard let image = UIImage(data: data) else {
|
|
throw APIError.invalidResponse
|
|
}
|
|
|
|
cache.setObject(image, forKey: url as NSURL)
|
|
return image
|
|
}
|
|
}
|