import Combine import SwiftUI final class ImageCacheManager { // MARK: - Singleton static let shared = ImageCacheManager() // MARK: - Private Properties private let cache = URLCache( memoryCapacity: 100 * 1_024 * 1_024, // 100 MB diskCapacity: 500 * 1_024 * 1_024, // 500 MB directory: FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first? .appendingPathComponent("SoraImageCache", isDirectory: true) ) private var cancellables = Set() private let cancellablesQueue = DispatchQueue( label: "\(Bundle.main.bundleIdentifier!).ImageCacheManager.cancellablesQueue" ) private let downloadQueue = OperationQueue() // MARK: - Initialisation private init() { downloadQueue.maxConcurrentOperationCount = 5 } // MARK: - Public Methods func preloadImages(_ urls: [URL]) { urls.forEach { url in downloadQueue.addOperation { self.cancellablesQueue.sync { URLSession.shared.dataTaskPublisher(for: url) .map { CachedURLResponse(response: $0.response, data: $0.data) } .sink( receiveCompletion: { _ in () }, receiveValue: { [self] in cache.storeCachedResponse($0, for: URLRequest(url: url)) } ) .store(in: &self.cancellables) } } } } }