import SwiftUI import Combine // 1. Класс для загрузки изображения с поддержкой кеширования class ImageLoader: ObservableObject { @Published var image: UIImage? private var cancellable: AnyCancellable? private let url: URL private let cache = ImageCacheManager.shared init(url: URL) { self.url = url } deinit { cancellable?.cancel() } func load() { // Проверяем, есть ли изображение в кеше if let cachedImage = cache.get(forKey: url.absoluteString) { self.image = cachedImage return } // Если в кеше нет, загружаем из сети cancellable = URLSession.shared.dataTaskPublisher(for: url) .map { UIImage(data: $0.data) } .replaceError(with: nil) .handleEvents(receiveOutput: { [weak self] image in // Сохраняем загруженное изображение в кеш if let image = image, let key = self?.url.absoluteString { self?.cache.set(image, forKey: key) } }) .receive(on: DispatchQueue.main) .assign(to: \.image, on: self) } func cancel() { cancellable?.cancel() } } // 2. View для отображения удаленного изображения struct RemoteImageView: View { @StateObject private var loader: ImageLoader init(url: URL) { _loader = StateObject(wrappedValue: ImageLoader(url: url)) } var body: some View { content .onAppear(perform: loader.load) .onDisappear(perform: loader.cancel) } private var content: some View { Group { if let image = loader.image { Image(uiImage: image) .resizable() } else { ProgressView() // Показываем индикатор загрузки } } } }