#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. Спасибо за ваш ответ. Теперь, если я запускаю свой симулятор, я получаю свою печать «изображение сохранено», и когда я перехожу на другую страницу и переворачиваю свой Интернет, а затем возвращаюсь на страницу, на которой у меня есть мое изображение, моя печать говорит «Изображение из кэша». Так что в некотором роде это работает. Но если я закрою свое приложение и снова запущу симулятор без подключения к Интернету, мое изображение не отображается. Должно ли изображение отображаться после перезагрузки или я ошибаюсь?