Firebase上传图片并获取网址问题 [英] Firebase Upload Images and getting URL issue

查看:232
本文介绍了Firebase上传图片并获取网址问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试拍摄3张图片并将其发布到firebase存储中,并获取下载网址并将其放入Firebase数据库。我的代码只上传第一张图片,但不会上传任何东西。

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

var ref:DatabaseReference?
$ b重写func viewDidLoad(){

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

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


$ b覆盖func didReceiveMemoryWarning {
super.didReceiveMemoryWarning()
}
$ b 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 :任何]){
如果让图像=信息[UIImagePickerControllerOriginalImage]作为? UIImage {
如果让myImageView1 = self.view.viewWithTag(选择)为? UIImageView {
myImageView1.image = image
}
} else {
//错误
}
self.dismiss(animated:true,completion:nil )

$ b @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,元数据:nil,完成:{$ metadata,error)in
$ b $ let storageRef2 = Storage.storage()。reference()。child(images2 / \(NSUUID()。uuidString) /image2.png)
如果让uploadData2 = UIImagePNGRepresentation(self.myImageView2.image!){
$ b $ storageRef2.putData(uploadData2,元数据:nil,完成:{(metadataSecond,error) in

if error!= nil {
print(error)
retu
} 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 ),下载URL 2:(downloadURL2)])

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

}


解决方案

如果我了解了您的图片浏览, imageviews和每一个用户可以从中挑选图像。



记住,当前的代码只处理一个例子,即 myImageView1 ,但是没有对 myImageView2 myImageView3



1。可扩展的解决方案



你需要做的是把你的图像浏览到一个数组,然后遍历这个数组,并开始上传每个图像。 b
$ b

PS: 这段代码没有经过测试,只是作为参考

在你的 viewDidLoad()中创建一个包含你的图像视图的数组,如下所示

  var imageViews:[UIImageView] 

重写func viewDidLoad()
{
//初始化后
imageViews = [myImageView1,myImageView2 ,myImageView3]
}

由于您有一个 code>>跟踪被截取的imageView的变量,我们也可以使用它来访问我们数组中的相应视图,如下所示

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

$ c> upload ,你想迭代 imageViews 并开始上传每个图片。

  @IBAction func上传(_ sender:Any)
{
let storageRef = Storage.storage()。reference()。child(images / (imageView.image)
{
如果让uploadData = UIImagePNGRepresentation(imageView.image)


$ image for imageViews
{

//继续你的东西
}
else
{
//上传数据创建错误
}
}
}

2。不可扩展

只需在 imagePickerController(_ picker:UIImagePickerController,didFinishPickingMediaWithInfo info:[String:Any])中写入多个if语句来解释 myImageView2 myImageView3



$ p

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

>

在上面的实现中,假定用户将按顺序选择所有的图像视图,即:imageView1-> imageView2-> imageView3-> imageView4-> imageView5- >等。如果用户选择 imageView1-> imageView3-> imageView5

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


$ b $ pre $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ - > [有图像]
[3] - > [无]
[4] - > [有图像]

当试图创建 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)
{
//继续你的东西
}
else
{
//上传数据创建错误
}
}

}
}


I am trying to take 3 images and post it in firebase storage and get a download URL and put it in the Firebase Database. My code only uploads the first image but won't upload anything if there is a second.

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

}

解决方案

If I understood your imageviews, it seems like you have multiple imageviews and for each one the user is able to pick an image from.

With this in mind, your current code handles just one case i.e. myImageView1, but no handling is performed for myImageView2 and myImageView3.

1. Scalable Solution

What you need to do is put your imageviews in an array, then iterate through this array and start uploading each image.

PS: This code isn't tested and is meant to be used as a reference

Create the array holding your imageviews in your viewDidLoad() as shown below

var imageViews: [UIImageView]

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

Since you have a selected variable that keeps track of the imageView that was tapped, we can use it as well to access the respective views in our array as shown below

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

In your upload, you want to iterate over imageViews and start uploading each respective image.

@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. Non-scalable

Just write multiple if statements in imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) to account for myImageView2 and myImageView3

Two Cents:

I'd recommend the first solution because its not limited by the number of imageviews you currently have. Should you opt to add more in the future, simply append it to the array. The second solution though, leads to multiple if statements and convoluted code.

Edit 1 Bug Discovered

In the above implementation, it assumes that the user will select all the image views in a sequential order i.e. imageView1->imageView2->imageView3->imageView4->imageView5->etc. What if the user selects imageView1->imageView3->imageView5?

Our array will look like this in the above scenario:

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

The nil segments will result into a crash when trying to create a UIImagePNGRepresentation.

A simple image existence check prior to uploading will resolve this issue.

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

    }
}

这篇关于Firebase上传图片并获取网址问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆