Reputation: 299
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)
}
Upvotes: 0
Views: 614
Reputation: 1507
try this for three images at the same time in the beginning of the class you add a counter
var counter: Int = 0
and then you modify 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)
}
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!
Upvotes: 0
Reputation: 3867
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
}
}
}
}
Upvotes: 1