问题描述
此处的代码允许我将一张照片上传并下载到Firebase,并将其保存为用户默认设置,但我试图弄清楚如何在collectionView单元中进行操作并显示所需的照片,并添加新项目
import UIKit
import FirebaseStorage
class ViewController: UIViewController,UINavigationControllerDelegate,UIImagePickerControllerDelegate {
private let storage = Storage.storage().reference()
@IBOutlet var imageView: UIImageView!
@IBOutlet var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
label.numberOfLines = 0
guard let urlString = UserDefaults.standard.value(forKey: "url") as? String,let url = URL(string: urlString) else {
return
}
label.text = urlString
let task = URLSession.shared.dataTask(with: url,completionHandler: { data,_,error in
guard let data = data,error == nil else {
return
}
dispatchQueue.main.async {
let image = UIImage(data: data)
self.imageView.image = image
}
})
task.resume()
}
@IBAction func didTapButton() {
let picker = UIImagePickerController()
picker.sourceType = .photoLibrary
picker.delegate = self
picker.allowsEditing = true
present(picker,animated: true,completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediawithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true,completion: nil)
guard let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage else {
return
}
guard let imageData = image.pngData() else {
return
}
storage.child("Images/Photo.png").putData(imageData,Metadata: nil) { (_,error) in
guard error == nil else {
print("Failed to Upload Data")
return
}
self.storage.child("Images/Photo.png").downloadURL(completion: {url,error in
guard let url = url,error == nil else {
return
}
let urlString = url.absoluteString
dispatchQueue.main.async {
self.label.text = urlString
self.imageView.image = image
}
print("Download URL: \(urlString)")
UserDefaults.standard.set(urlString,forKey: "url")
})
}
// Upload Image Data
// Get Download URL
// Save Download URL to userDefaults
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true,completion: nil)
}
}
解决方法
要将图像上传到Firebase存储并在集合视图中显示它们,您可以使用以下步骤;
-
使用
URL
(或String
s)数组作为集合视图来设置集合视图 数据源。您可以根据需要使用自定义模型。 -
保留对您的
Firebase storage
的引用并上传图片。成功上传后,使用image reference
获取上传图像的URL。 -
将网址保存在
Firebase Database
(或Cloud Firestore
)中。仅当您要将集合视图与数据库同步并在上传新图像时对其进行更新时,才需要这样做。 -
在您拥有的
Firebase database
参考中添加一个侦听器 保存了图片网址。更新侦听器内部的本地URL数组,然后重新加载集合视图。
如果您不想使用Firebase database
,请省略第3步和第4步,将图像URL保存到数组中并立即重新加载集合视图。
我不在此处添加用于集合视图设置的代码,因为这不是此答案的目的。
let storageRef = Storage.storage().reference(withPath: "images")
let databaseRef = Database.database().reference(withPath:"images")
var images: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
addDatabaseListener()
}
private func addDatabaseListener() {
databaseRef.observe(.childAdded) { (snapshot) in
guard let value = snapshot.value as? [String: Any],let url = value["url"] as? String else { return }
self.images.append(url)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true)
guard let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage,let data = image.jpegData(compressionQuality: 0.1) else { return }
let fileName = "\(Date.timeIntervalSinceReferenceDate).jpeg"
let newImageRef = storageRef.child(fileName)
newImageRef.putData(data,metadata: nil) { (_,error) in
if let error = error {
print("upload failed: ",error.localizedDescription)
return
}
newImageRef.downloadURL { (url,error) in
if let error = error {
print("error: ",error.localizedDescription)
return
}
self.databaseRef.childByAutoId().setValue(["url": url?.absoluteString])
}
}
}