ios - Firebase 上传图片和获取 URL 问题

标签 ios swift firebase swift3 firebase-realtime-database

我正在尝试拍摄 3 张图片并将其发布到 firebase 存储中,然后获取下载 URL 并将其放入 Firebase 数据库中。我的代码只上传第一张图片,但如果有第二张则不会上传任何内容。

@IBOutlet weak var titleText: UITextField!
@IBOutlet weak var subtitleText: UITextField!
@IBOutlet weak var authorText: UITextField!
@IBOutlet weak var dateText: UITextField!
@IBOutlet weak var articleText: UITextView!
@IBOutlet weak var tagsText: UITextField!
@IBOutlet weak var myImageView1: UIImageView!
@IBOutlet weak var myImageView2: UIImageView!
@IBOutlet weak var myImageView3: UIImageView!
@IBOutlet weak var postType: UITextField!
@IBOutlet weak var postStyle: UITextField!

var ref:DatabaseReference?

override func viewDidLoad() {

    super.viewDidLoad()  
    ref = Database.database().reference()  

    let tapGestureRecognizer1 = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
    myImageView1.isUserInteractionEnabled = true
    myImageView1.addGestureRecognizer(tapGestureRecognizer1)
    let tapGestureRecognizer2 = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
    myImageView2.isUserInteractionEnabled = true
    myImageView2.addGestureRecognizer(tapGestureRecognizer2)
    let tapGestureRecognizer3 = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
    myImageView3.isUserInteractionEnabled = true
    myImageView3.addGestureRecognizer(tapGestureRecognizer3)        

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

var selected = 0

func imageTapped(tapGestureRecognizer: UITapGestureRecognizer){
    let image = UIImagePickerController()
    image.delegate = self
    image.sourceType = UIImagePickerControllerSourceType.photoLibrary
    image.allowsEditing = false
    let tappedImage = tapGestureRecognizer.view as! UIImageView
    selected = tappedImage.tag
    self.present(image, animated: true)
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        if let myImageView1 = self.view.viewWithTag(selected) as? UIImageView {
            myImageView1.image = image
        }
    } else {
        //error
    }
    self.dismiss(animated: true, completion: nil)
}

@IBAction func upload(_ sender: Any) {

    let storageRef = Storage.storage().reference().child("images/\(NSUUID().uuidString)/image.png")

    if let uploadData = UIImagePNGRepresentation(self.myImageView1.image!) {

        storageRef.putData(uploadData, metadata: nil, completion: { (metadata, error) in 

            let storageRef2 = Storage.storage().reference().child("images2/\(NSUUID().uuidString)/image2.png")
            if let uploadData2 = UIImagePNGRepresentation(self.myImageView2.image!) {

                storageRef2.putData(uploadData2, metadata: nil, completion: { (metadataSecond, error) in

                    if error != nil {
                        print("error")
                        return              
                    } else {
                        let downloadURL = metadata?.downloadURL()?.absoluteString
                        let downloadURL2 = metadataSecond?.downloadURL()?.absoluteString
                                  self.ref?.child("Posts").childByAutoId().setValue(["Title": self.titleText.text, "Subtitle": self.subtitleText.text, "Article": self.articleText.text, "Author": self.authorText.text, "Date": self.dateText.text, "Tags": self.tagsText.text, "PostType": self.postType.text, "PostStyle": self.postStyle.text, "Download URL": (downloadURL), "Download URL 2": (downloadURL2)])

                    }
                    self.performSegue(withIdentifier: "segue321", sender: self)

}

最佳答案

如果我了解您的图片 View ,您似乎有多个图片 View ,并且用户可以从每个图片 View 中选择一张图片。

考虑到这一点,您当前的代码只处理一种情况,即 myImageView1,但不会对 myImageView2myImageView3 执行任何处理。

<强>1。可扩展的解决方案

您需要做的是将 ImageView 放入一个数组中,然后遍历该数组并开始上传每张图片。

PS: 此代码未经测试,仅供引用

viewDidLoad() 中创建保存 ImageView 的数组,如下所示

var imageViews: [UIImageView]

override func viewDidLoad() 
{
    // After initializing them 
    imageViews = [myImageView1, myImageView2, myImageView3]
}

因为您有一个 selected 变量来跟踪被点击的 imageView,我们也可以使用它来访问数组中的各个 View ,如下所示

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 
{
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage
    {
        imageViews[selected].image = image
    } 
    else 
    {
        //error
    }
    self.dismiss(animated: true, completion: nil)
}

在您的上传中,您想要遍历imageViews 并开始上传每个相应的图像。

@IBAction func upload(_ sender: Any) 
{
    let storageRef = Storage.storage().reference().child("images/\(NSUUID().uuidString)/image.png")

    for imageView in imageViews
    {
        if let uploadData = UIImagePNGRepresentation(imageView.image)
        {
            // continue with your stuff
        }
        else
        {
            // Upload Data creation error
        }
    }
}

<强>2。不可扩展

只需在 imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 中编写多个 if 语句来说明 myImageView2myImageView3

两分钱:

我推荐第一种解决方案,因为它不受您当前拥有的 ImageView 数量的限制。如果您将来选择添加更多,只需将其附加到数组即可。不过,第二种解决方案会导致多个 if 语句和复杂的代码。

编辑 1 发现错误

在上面的实现中,假设用户将按顺序选择所有 ImageView ,即 imageView1->imageView2->imageView3->imageView4->imageView5->etc。如果用户选择 imageView1->imageView3->imageView5 会怎样?

在上面的场景中我们的数组看起来像这样:

[0]->[has image]
[1]->[nil]
[2]->[has image]
[3]->[nil]
[4]->[has image]

尝试创建 UIImagePNGRepresentation 时,零段将导致崩溃。

在上传之前进行简单的图片存在性检查即可解决此问题。

@IBAction func upload(_ sender: Any) 
{
    let storageRef = Storage.storage().reference().child("images/\(NSUUID().uuidString)/image.png")

    for imageView in imageViews
    {
        if imageView.image != nil
        {
            if let uploadData = UIImagePNGRepresentation(imageView.image)
            {
                // continue with your stuff
            }
            else
            {
                // upload data creation error
            }
        }

    }
}

关于ios - Firebase 上传图片和获取 URL 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44978704/

相关文章:

ios - 如何在 git 上共享 Xcode 性能测试基线?

ios - CABasicAnimation 不适用于设备 (iPhone 5s)

android - 如何提高 Android/iOS/etc 使用 web 服务的性能?

swift - 如何展平可选的异构值数组

javascript - firestore 查询中的条件 where 子句

iphone - 导航 Controller 注销

ios - 如何使搜索栏在表格 View 中滚动时不消失?

ios - _validateTextureView :557: failed assertion `Texture View Validation cannot create View from Memoryless texture

firebase - 将 firebase 存储设置为只写

ios - Firestorage 关闭时显示图像的正确方法或在 Firestorage for iOS 中加载预览时出错