如何防止不断从 Firebase 下载图像并显示图像,即使没有互联网连接?

How to prevent constantly downloading an image from Firebase and show the image even if there is no internet connection?

每次我显示个人资料图片时,UIImageView 都会闪烁,表示该图片刚刚从 Firebase 存储 URL 下载。此下载速度因设备类型而异,有时不明显,有时则有明显延迟。

我尝试使用 NSCacheKingfisher 库缓存图像,但我仍然看到 UIImageView 闪烁,而不是每次重新打开应用程序时都保留在那里。

我最后一次尝试是将图像保存到文档目录,然后从那里检索它,但我仍然看到图像闪烁。我也希望即使在没有任何互联网连接的情况下打开应用程序,个人资料图片也保留在那里。

func saveImageDocumentDirectory(imgUrl: URL){
    let fileManager = FileManager.default
    let paths =     (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("proPic.png")
    let data = (try? Data(contentsOf: imgUrl))
    let image = UIImage(data: data!)
    print("\n\(paths)\n")
    let imageData = image!.pngData()
    fileManager.createFile(atPath: paths as String, contents: imageData, attributes: nil)
}


func getDirectoryPath() -> String {
    let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
    let documentsDirectory = paths[0]
    return documentsDirectory
}

func getImage(){
    let fileManager = FileManager.default
    let imagePAth = (self.getDirectoryPath() as NSString).appendingPathComponent("proPic.png")
    if fileManager.fileExists(atPath: imagePAth){
        self.profilePic.image = UIImage(contentsOfFile: imagePAth)
    }else{
        print("\nNo Image\n")
    }
}

func createDirectory(){
    let fileManager = FileManager.default
    let paths = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("customDirectory")
    if !fileManager.fileExists(atPath: paths){
        try! fileManager.createDirectory(atPath: paths, withIntermediateDirectories: true, attributes: nil)
    }else{
        print("\nAlready dictionary created.\n")
    }
}

我会通过以下方式调用该函数:

func getEmailPic(){


    guard let uid = Auth.auth().currentUser?.uid else {return}

    //receive the location of the profile pic
    let storageRef = Storage.storage().reference().child(uid).child("profilePic.png");

    //how to access the downloadURL
    _ = storageRef.downloadURL(completion: { (URLe, error) in
    if let error = error{

        //error handling
        print("\nCould not download user's profile image from url. 
     Error: \(error.localizedDescription)\n");
        return;
    }

            self.createDirectory()
            self.saveImageDocumentDirectory(imgUrl: URLe!)
            print("\nThis is the URL: \(URLe)\n")
            self.getImage()

    })

}

在 viewDidLoad 中。

使用 kingfisher 进行图片缓存,试试这个,如果遇到任何问题,请随时询问

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    // set profile image if you have url saved in userdefaults
    let imageUrl = getUrlImageFromUserDefaults()
    let placeholderImage = UIImage(named: "placeholder")
    profileImageView.kf.setImage(with: imageUrl, placeholder: placeholderImage)
    getEmailPic()
}

func getUrlImageFromUserDefaults() -> URL?{
    // save image URL to userdefault and fetch here
    let userdefaults = UserDefaults.standard

    return userdefaults.url(forKey: "profileURL")
}
func getEmailPic(){


    guard let uid = Auth.auth().currentUser?.uid else {return}

    //receive the location of the profile pic
    let storageRef = Storage.storage().reference().child(uid).child("profilePic.png");

    //how to access the downloadURL
    _ = storageRef.downloadURL(completion: { (URLe, error) in
        if let error = error{

            //error handling
            print("\nCould not download user's profile image from url.
                Error: \(error.localizedDescription)\n");
                return;
        }

        if URLe == getUrlImageFromUserDefaults() {
            // if url is same no need to set again
        }else{
            // set profile image
            let placeholderImage = UIImage(named: "placeholder")
            profileImageView.kf.setImage(with: URLe, placeholder: placeholderImage)
            // and again save this new URL to userdefaults
        }

    })

}