如何从 Firebase 加载图像到用户头像

How to load image from Firebase into users avatar

我在从 firebase 加载图像时遇到问题。我有两个功能。其中之一收集有关用户的信息,第二个加载用户头像图像。不幸的是,图像在函数创建新用户后加载。我知道 Firebase 的异步会出现问题,但我不知道如何设置 DispatchQueue 才能正常工作。你能帮我吗?

// 在用户管理器中加载用户图像的函数 class

func loadUserImage(contactUserID: String, completion: @escaping (UIImage) -> Void) {
        let userID = Auth.auth().currentUser!.uid
        var userImageRef = self.storage.child("\(userID)/userImage.jpg")
        var image = UIImage()

        if contactUserID != "" {
            userImageRef = self.storage.child("\(contactUserID)/userImage.jpg")
        }
        userImageRef.getData(maxSize: 5 * 1024 * 1024) { (data, error) in
            if let error = error {
                print("Error with retrieving data: \(error.localizedDescription)")
            } else {
                if data?.count != 0 {
                    image = UIImage(data: data!)!
                } else {
                    image = UIImage(systemName: "person.circle.fill")!
                }
                completion(image)
            }
        }
    }

// 在联系人管理器中加载用户的函数 class

func loadContactList(completion: @escaping ([User]) -> Void) {
    let currentUserID = Auth.auth().currentUser!.uid
    db.collection("contacts")
        .document(currentUserID)
        .collection("userContacts")
        .addSnapshotListener { (querySnapshot, error) in
            var contactList = [User]()
            if let error = error {
                print("Error with retrieving data from DB: \(error.localizedDescription)")
            } else {
                if let snapshotDocuments = querySnapshot?.documents {
                    for document in snapshotDocuments {
                        let data = document.data()
                        let uid = data["uid"] as! String
                        let name = data["name"] as! String
                        let email = data["email"] as! String
                        var contact = User(email: email, name: name, userID: uid)

                        DispatchQueue.global().sync {
                            self.userService.loadUserImage(contactUserID: uid) { (image) in
                                contact.photoURL = image
                            }
                        }
                        contactList.append(contact)

                        contactList.sort {
                            [=11=].name < .name
                        }
                        completion(contactList)
                    }
                }
            }
        }
}

// viewController

中的函数实现
func loadContactList() {
    self.contactService.loadContactList { (contactArray) in
        self.contactList = contactArray
        self.tableView.reloadData()
    }
}

您可以做的是将图像 url 存储在 firebase 数据库中,然后创建此扩展程序:

import UIKit

let imageCache: NSCache = NSCache<AnyObject, AnyObject>()

extension UIImageView {
    
    func loadImageUsingCacheWithUrlString(urlString: String) {
        
        self.image = nil
        
        if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
            self.image = cachedImage
            return
        }
        
        let url = URL(string: urlString)
        if let data = try? Data(contentsOf: url!) {
            
            DispatchQueue.main.async(execute: {
                
                if let downloadedImage = UIImage(data: data) {
                    imageCache.setObject(downloadedImage, forKey: urlString as AnyObject)
                    
                    self.image = downloadedImage
                }
            })
        }
    }
}

然后调用:

if let url = data["imgUrl"] as? String {
    self.myImageView.loadImageUsingCacheWithUrlString(urlString: url)
}

为此,您需要做的是创建并初始化一个 UIImage 对象。如果您正在使用单元格 类,则需要在单元格中创建此对象。