【问题标题】:Firebase Upload Images and getting URL issueFirebase 上传图片并获取 URL 问题
【发布时间】:2017-12-12 05:16:38
【问题描述】:

我正在尝试拍摄 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)

}

【问题讨论】:

  • 看起来您在imagePickerController 函数中将图像分配给myImageView1,但其他UIImageViews 没有分配图像。不过,我可能误解了您在代码中选择图像的位置。
  • 那么它应该是什么样子?
  • 在图片 1 上传关闭中放置一个断点。你的闭包被调用了吗?如果是这样,由于您的第二张图片未上传,它在哪里失败?
  • @Riccardo 检查我的编辑是否有修补的错误

标签: ios swift firebase swift3 firebase-realtime-database


【解决方案1】:

同时尝试三张图片 在课程的开头添加一个计数器

var counter: Int = 0

然后你修改 imagePickerController: `

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 
{

    if counter == 0{
        if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
            if let myImageView1 = self.view.viewWithTag(selected) as? UIImageView {
                myImageView1.image = image
                counter +=1
            }
        } else {
            //error
        }
      }
      else if counter==1{
          if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
            if let myImageView2 = self.view.viewWithTag(selected) as? UIImageView {
                myImageView2.image = image
                counter+=1
            }
        } else {
            //error
        }
      else{
        if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
          if let myImageView3 = self.view.viewWithTag(selected) as? UIImageView {
            myImageView3.image = image
            counter = 0
        }
    } else {
        //error
    }
    }
    self.dismiss(animated: true, completion: nil)
}

我不知道它是否一次只能用于两个图像,但一次可以用于三个图像。对于其他情况,您应该自己尝试一下!

【讨论】:

  • 如果我想添加第四张图片怎么办?
  • @ricardo 第四张图片喜欢添加另一个图像视图并添加另一个图像?如果这就是你的意思,你添加另一个如果计数器 == 3 并且当你为第三个实现计数器时,计数器变为 4 ......并且第四个图像与旧的第三个图像相同,但你改变了你的数字从 3 到 4
  • 它令人困惑。不是很懂
【解决方案2】:

如果我理解您的图像视图,您似乎有多个图像视图,并且用户可以从每个图像视图中选择一个图像。

考虑到这一点,您当前的代码只处理一种情况,即myImageView1,但不处理myImageView2myImageView3

1.可扩展的解决方案

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

PS: 此代码未经测试,仅供参考

viewDidLoad() 中创建包含您的图像视图的数组,如下所示

var imageViews: [UIImageView]

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

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

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)
}

在您的upload 中,您希望遍历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

两分钱:

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

编辑 1 发现错误

在上述实现中,假设用户将按顺序选择所有图像视图,即 imageView1->imageView2->imageView3->imageView4->imageView5->etc。如果用户选择imageView1->imageView3->imageView5怎么办?

在上述场景中,我们的数组将如下所示:

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

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

在上传之前进行简单的图像存在检查将解决此问题。

@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
            }
        }

    }
}

【讨论】:

    猜你喜欢
    • 2017-09-19
    • 2021-01-24
    • 2020-04-18
    • 2019-01-24
    • 2021-07-13
    • 1970-01-01
    • 2017-06-02
    • 2016-09-27
    • 2018-07-19
    相关资源
    最近更新 更多