如何从 firebase-storage 下载图像以显示在 collectionViewCell 的 Imageview 中(Swift)

How to download image from firebase-storage to display inside collectionViewCell's Imageview(Swift)

我已将图像上传到 firebase-storage 并将下载 URL 保存到我数据库中的 key/value 对中。我编写了一段代码,如果 url 有效,一旦检索到数据,就可以在 collectionView 中显示图像。代码在 cellForItemAt 处执行,因为包含图片的 collectionView 嵌入到另一个 collectionView 中(将称为 Main 或 MainCV 以防止混淆)。

为了解决这个问题,我尝试在 MainCV 中重新加载集合视图的数据,并尝试在仅使用 ImageView 的视图控制器上测试代码(未成功)。

// function to display images
private func icon(_ imageURL: String) -> UIImage {
        //print("imageURL is \(imageURL)")
        let url = URL(string: imageURL)
        var image: UIImage?
        var imageData:Data?
        if url == nil {
            print("URL is \(imageURL)")
            return #imageLiteral(resourceName: "ic_person_outline_white_2x")
        } else {
            URLSession.shared.dataTask(with: url!) { (data, response, error) in
                if error != nil {
                    print("error")
                    return
                }
                DispatchQueue.main.async {
                    imageData = data
                    image = UIImage(data: imageData!)
                }
                }.resume()
            return image ?? #imageLiteral(resourceName: "ic_person_outline_white_2x")
        }
    }

CellForItemAt 代码块

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ImageCell
        let imageOption = self.imageData[indexPath.row]
        cell.iconImageView.image = icon(imageOption)
        return cell
        //imageData is an array with empty values that is populated with database values and subsequently reloaded
    }

正如我之前所说的预期结果是在 collectionView 中显示来自 firebaseStorage 的图像。我的代码没有呈现任何错误,但总是 returns 默认图像以及打印 imageURl,我确认它是我要显示的图像的准确 http。

您需要学习一些有关异步编程的知识。

您的功能 return 立即生效,但 URLSession.shared.dataTask(with: url!) 需要一些时间。时间线:

  1. 图片=无
  2. 开始获取数据
  3. return 图片??默认图片
  4. 获取数据完成(在函数 returned -> 图像数据丢失后)

与其立即 returning,不如提供将图像作为参数的闭包:

private func icon(_ imageURL: String, closure: (UIImage) -> Void)

并将您的代码更新为

URLSession.shared.dataTask(with: url!) { (data, response, error) in
    if error != nil {
        print("error")
        closure(#imageLiteral(resourceName: "ic_person_outline_white_2x"))
    }
    DispatchQueue.main.async {
        imageData = data
        image = UIImage(data: imageData!)
        closure(image)
    }
}.resume()

闭包本身可以是一个接受图像作为参数并将该图像异步设置到您的集合视图单元格

的函数

此外,您还想在加载图像之前提供一些默认图像或加载图像。或者使用 ActivityIndi​​cator。

希望对您有所帮助!