【问题标题】:How to prevent constantly downloading an image from Firebase and show the image even if there is no internet connection?即使没有互联网连接,如何防止不断从 Firebase 下载图像并显示图像?
【发布时间】:2019-07-15 04:43:15
【问题描述】:

每次我显示个人资料图片时,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 中。

【问题讨论】:

  • 从哪里调用异步函数?
  • 我有另一个函数可以抓取存储在 Firebase 存储中的图像的 URL
  • 所以在 viewDidLoad 中你应该将缓存的个人资料图片设置为你的 UIImageView,当你从 firebase 获取 URL 时检查它是否改变了然后根据那个设置或不设置。
  • 问题是我从来没有真正拥有缓存图像。我不知道为什么图像一直闪烁。
  • 无论您尝试什么方法,都应该有效,但我认为您做错了其他事情,使用提供的代码很难调试您的问题

标签: ios swift firebase firebase-storage profile-picture


【解决方案1】:

使用 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
        }

    })

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    相关资源
    最近更新 更多