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 formyImageView2
andmyImageView3
.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 belowSince 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 belowIn your
upload
, you want to iterate overimageViews
and start uploading each respective image.2. Non-scalable
Just write multiple if statements in
imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
to account formyImageView2
andmyImageView3
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:
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.
try this for three images at the same time in the beginning of the class you add a counter
and then you modify imagePickerController: `
I dont know if it's gonna work for only two images at a time, but for three at a time its gonna work. For other cases you should give it a try yourself!