简体   繁体   English

如何防止即使没有Internet连接也不断从Firebase下载图像并显示图像?

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

Every time I show the profile picture, the UIImageView flashes to signify that the image was just downloaded from the Firebase Storage URL. 每次显示个人资料图片时, UIImageView闪烁,以表示该图像是刚从Firebase存储URL下载的。 This download speed differs based on the device type, some times it is unnoticeable while other times there is a significant delay. 此下载速度因设备类型而异,有时不太明显,而另一些时候则存在明显的延迟。

I have attempted to cache the image with NSCache and the Kingfisher library but I still see the UIImageView flash rather than remain there every time I reopen the app. 我曾尝试使用NSCacheKingfisher库来缓存图像,但是我仍然看到UIImageView闪存,而不是每次重新打开应用程序时都停留在那里。

My last attempt was to save the image to the document directory and then retrieve it from there but I still see the image flash. 我最后的尝试是将图像保存到文档目录,然后从那里检索它,但是我仍然看到图像闪烁。 I would also like the profile picture to remain there even if the application is opened without any internet connection. 即使应用程序在没有任何互联网连接的情况下打开,我也希望个人资料图片保留在那里。

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")
    }
}

And I would call the function by: 我将通过以下方式调用该函数:

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()

    })

}

in viewDidLoad. 在viewDidLoad中。

Using kingfisher for image caching, Try this and feel free to ask if facing any issue 使用翠鸟进行图像缓存,尝试一下并随意询问是否遇到任何问题

    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
        }

    })

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM