如何从firebase存储下载图像以在collectionViewCell';s图像视图(Swift)

如何从firebase存储下载图像以在collectionViewCell';s图像视图(Swift),swift,uicollectionview,uiimage,uicollectionviewcell,firebase-storage,Swift,Uicollectionview,Uiimage,Uicollectionviewcell,Firebase Storage,我已将一个图像上载到firebase存储中,并将下载的URL保存到数据库中的一个键/值对中。我编写了一段代码,假设在检索到数据后,如果url有效,则在collectionView中显示图像。代码在cellForItemAt执行,因为包含图片的collectionView嵌入到另一个collectionView中(称为Main或MainCV以防止混淆) 为了解决这个问题,我尝试在MainCV中重新加载集合视图的数据,并尝试在仅使用ImageView的视图控制器上测试代码(未成功) //显示图像的函

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

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

//显示图像的函数
私有函数图标(imageURL:String)->UIImage{
//打印(“imageURL为\(imageURL)”)
让url=url(字符串:imageURL)
var图像:UIImage?
var imageData:数据?
如果url==nil{
打印(“URL为\(imageURL)”)
返回#imageLiteral(resourceName:“ic_person_outline_white_2x”)
}否则{
URLSession.shared.dataTask(带有:url!){(数据、响应、错误)在
如果错误!=nil{
打印(“错误”)
返回
}
DispatchQueue.main.async{
图像数据=数据
image=UIImage(数据:imageData!)
}
}1.简历()
返回图像???imageLiteral(resourceName:“ic_person_outline_white_2x”)
}
}
CellForItemAt代码块

func collectionView(collectionView:UICollectionView,cellForItemAt indexPath:indexPath)->UICollectionViewCell{
让cell=collectionView.dequeueReusableCell(withReuseIdentifier:cellId,for:indexPath)作为!ImageCell
让imageOption=self.imageData[indexPath.row]
cell.iconImageView.image=图标(imageOption)
返回单元
//imageData是一个包含空值的数组,该空值由数据库值填充并随后重新加载
}

正如我前面所说,预期的结果是在collectionView中显示firebaseStorage中的图像。我的代码不会呈现任何错误,但总是返回默认图像并打印imageURl,我确认它是我试图显示的图像的准确http。

您需要了解一些异步编程的知识

您的函数立即返回,但是
URLSession.shared.dataTask(with:url!)
需要一些时间。时间线:

  • 图像=零
  • 开始提取数据
  • 返回图像??默认图像
  • 获取数据完成(函数返回->图像数据丢失后)
  • 不要立即返回,而是将图像作为参数提供给函数:

    private func图标(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()
    
    闭包本身可以是一个函数,它接受图像作为参数,并将此图像异步设置为集合视图单元格

    此外,您希望在加载图像之前提供一些默认图像或加载图像。或者使用ActivityIndicator


    希望这有帮助

    它确实有用!!我目前正在学习异步函数,开发人员的注释对我来说并不总是很清楚。我唯一的问题是,是否有更快的方法从数据库中提取数据。我的应用程序最近开始在后台线程调用我的UIImage时崩溃。我正在查看开发人员的注释,看起来我的操作是正确的,但是我得到了错误所有UI内容都必须从主线程调用。如果启动dataTask,将在后台线程上调用响应。要将其返回主线程,请将其包装到
    DispatchQueue.main.async{您的代码在这里}