Образ кэша swift

#swift #firebase #caching

# #swift #firebase #кэширование

Вопрос:

Я пытаюсь кэшировать изображение из URL-адреса из моего хранилища firebase. если я напечатаю свой URL-адрес в функции «downloadImage», я увижу, что получаю URL-адрес изображения. Но я печатаю свой URL-адрес в своей функции getImage, затем ничего не отображается.

Здесь я использую свой сервис изображений:

 import Foundation
import UIKit
import Firebase

class ImageService {
    
    static let cache = NSCache<NSString, UIImage>()
    static let storage = Storage.storage()
    static let db = Firestore.firestore()
    
    // Downloading image with URL
    static func downloadImage(withURL url:URL, completion: @escaping (_ image:UIImage?, _ url:URL)->()) {
        let dataTask = URLSession.shared.dataTask(with: url) { data, responseURL, error in
            var downloadedImage:UIImage?
            
            if let data = data {
                downloadedImage = UIImage(data: data)
                
            }
            if downloadedImage != nil {
                cache.setObject(downloadedImage!, forKey: url.absoluteString as NSString)
               
            }
            DispatchQueue.main.async {
                completion(downloadedImage, url)
                
            }
        }
        dataTask.resume()
    }
    // Get the downloaded image
    static func getImage(withURL url:URL?, completion: @escaping (_ image:UIImage?, _ url:URL)->()) {
        if let _url = url {
            if let image = cache.object(forKey: _url.absoluteString as NSString) {
                completion(image, _url)
                print("HEJSAN(String(describing: url))")
            } else {
                downloadImage(withURL: _url, completion: completion)
            }
        }
    }
    
    // Set the retrieved image for the UIImageView
    static func setImage(imageView image: UIImageView, imageURL url: String) {
        getImage(withURL: URL(string: url)) { retrievedImage, error in
            image.image = retrievedImage
        }
    }

 

Вот как я пытаюсь отобразить его в своем ВК:

     override func viewDidLoad() {
        super.viewDidLoad()        
        ImageService.setImage(imageView: logoImage, imageURL: "https://firebasestorage.googleapis.com/v0/b/shutappios.appspot.com/o/LogoImage/ShutAppLogo.jpg?alt=mediaamp;token=13216931-418f-486a-9702-2985b262ab08")
    }
 

Комментарии:

1. Я не уверен, что вопрос ясен. Но я печатаю свой URL-адрес в своей функции getImage ? Функция getImage в качестве передаваемого вами параметра URL-адреса — вы утверждаете, что если вы передаете URL-адрес этой функции, URL-адрес будет пустым внутри функции? Вы добавили точку останова в каждую функцию и прошли по коду, чтобы увидеть, где она терпит неудачу?

Ответ №1:

Я не уверен, что хорошо понял ваш вопрос, но, исходя из того, что вы сказали, это нормально, что getImage при первом вызове будет выполняться downloadImage , потому что в кэше еще не будет изображения, но при втором вызове у него будет изображение. возможно, проблема здесь в том, что вы пытаетесь получить изображение из кэша до завершения загрузки изображения, потому что его код выполняется в фоновом режиме, асинхронность означает, что вы пытаетесь получить наличные деньги сразу после этого, не дожидаясь. Скорее всего, он не будет готов, поэтому, если вы хотите убедиться, что этого не произойдет, я думаю, вам нужно добавить завершение в вашу функцию setImage примерно так:

 static func setImage(
    imageView image: UIImageView,
    imageURL url: String,
    completion: (() -> ())? = nil) {
    getImage(withURL: URL(string: url)) { retrievedImage, error in
        image.image = retrievedImage
        completion?()
    }
}
 

в этом примере он будет печатать ваш журнал из getImage, как и ожидалось, при первой загрузке, а при второй — из кэша.

  ImageService.setImage(imageView: imageView, imageURL: imageURL) {
    ImageService.setImage(imageView: self.imageView, imageURL: imageURL)
 } 
 

Пожалуйста, обратите внимание, что это всего лишь пример, чтобы дать вам представление о том, в чем может быть проблема, стоящая за этим, я надеюсь, это поможет вам!

Комментарии:

1. Спасибо за ваш ответ. Теперь, если я запускаю свой симулятор, я получаю свою печать «изображение сохранено», и когда я перехожу на другую страницу и переворачиваю свой Интернет, а затем возвращаюсь на страницу, на которой у меня есть мое изображение, моя печать говорит «Изображение из кэша». Так что в некотором роде это работает. Но если я закрою свое приложение и снова запущу симулятор без подключения к Интернету, мое изображение не отображается. Должно ли изображение отображаться после перезагрузки или я ошибаюсь?