0

so in Swift, you have the ability to upload an image/video with ease using UIImageViewController. I did research and came across PHPickerController and I am trying to incorporate that into my code - for the reasoning being that I want multiple images/videos selected and once user presses "button" it pushes that batch to firebase cloud. I have been struggling with this for sometime now. Any sample swift file of doing just this would be much appreciated.

  • 1
    Can you include what you've tried so far? For example, are you having a problem using `PHPickerController` or do you have code for that? Do you know how to upload to firebase? Have you looked at their documentation and tried to implement that code yet? – jnpdx Dec 24 '21 at 00:47

1 Answers1

1

This worked for me.

Note: Make sure that the images you are selecting from the photoLibrary are not the default ones that come with xCode. Some of the default images do not work because they don't have a file location.

SwiftUI Solution

Here is how you call the PHPickerViewController:

struct PHPicker: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> PHPickerViewController {
    var config = PHPickerConfiguration()
    config.selectionLimit = 5
    config.filter = PHPickerFilter.images
    
    let pickerViewController = PHPickerViewController(configuration: config)
    pickerViewController.delegate = context.coordinator
    return pickerViewController
}

func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
}

class something: NSObject, PHPickerViewControllerDelegate {
    
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true)
        
        var fileName: Int = 5
        for result in results {
            
            // Get all the images that you selected from the PHPickerViewController
            result.itemProvider.loadObject(ofClass: UIImage.self) { object, error in
                // Check for errors
                if let error = error {
                    print("Sick error dawg \(error.localizedDescription)")
                } else {
                    // Convert the image into Data so we can upload to firebase
                    if let image = object as? UIImage {
                        let imageData = image.jpegData(compressionQuality: 1.0)
                        
                        // You NEED to make sure you somehow change the name of each picture that you upload which is why I am using the variable "count".
                        // If you do not change the filename for each picture you upload, it will try to upload the file to the same file and it will give you an error.
                        Storage.storage().reference().child("fileName").child("\(fileName)").putData(imageData!)
                        fileName += 1
                        print("Uploaded to firebase")
                    } else {
                        print("There was an error.")
                    }
                }
            }
        }
    }
}

func makeCoordinator() -> something {
    return something()
}

}

Here is how I present the sheet:

struct PresentMyPicker: View {

@State var presentSheet: Bool = false

var body: some View {
    VStack {
        Button {
            presentSheet.toggle()
        } label: {
            Text("Click me")
        }
    }
    .sheet(isPresented: $presentSheet) {
        PHPicker()
    }
}

}

UIKit solution

This is how I present the PHPickerViewController when they tap the button:

    func setupView() {
    var config = PHPickerConfiguration()
    config.selectionLimit = 5
    config.filter = PHPickerFilter.images
    
    let pickerViewController = PHPickerViewController(configuration: config)
    pickerViewController.delegate = self
    
    view.addSubview(button)
    button.addAction(UIAction() { _ in
        self.present(pickerViewController, animated: true)
    }, for: .touchUpInside)
}

Here is my delegate function that runs after you click "Add" with the selected images you want to upload.

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true)
    
    var fileName: Int = 1
    for result in results {
        
        // Get all the images that you selected from the PHPickerViewController
        result.itemProvider.loadObject(ofClass: UIImage.self) { object, error in
            // Check for errors
            if let error = error {
                print("Sick error dawg \(error.localizedDescription)")
            } else {
                // Convert the image into Data so we can upload to firebase
                if let image = object as? UIImage {
                    let imageData = image.jpegData(compressionQuality: 1.0)
                    
                    // You NEED to make sure you somehow change the name of each picture that you upload which is why I am using the variable "fileName".
                    // If you do not change the filename for each picture you upload, it will try to upload all the selected images to the same file location and give you an error.
                    Storage.storage().reference().child("CollectionName").child("\(fileName)").putData(imageData!)
                    fileName += 1
                } else {
                    print("There was an error.")
                }
            }
        }
    }
}

Also if you are wanting to upload videos to firebase and having trouble take a look at this example it took me forever to figure this out. Uploading Videos to firebase correctly.

Trev347
  • 318
  • 1
  • 12
  • Actually I don't think you need a `DispatchGroup()` I just tested it without it and it worked. – Trev347 Dec 24 '21 at 07:12
  • Hey Trevor! I tried incorporating this into my code. I am using SwiftUI, so I believe I will need a UIRepresentableController for my script along with it. I am honestly having trouble incorporating it. Can you sharing your full 2 swift files that has the button tied to it so I can better understand the code? My email is mfritzhand1@gmail.com. @Trev347 – Max Fritzhand Dec 24 '21 at 20:19
  • 1
    @Max Fritzhand I updated the answer to show how you can do this in swiftUI. – Trev347 Dec 25 '21 at 06:35
  • Thank you so much @Trev347 - next step is pushing the images to firebase! I may ping you further if I have questions regarding that- thank you so much again! Have a good happy holidays! – Max Fritzhand Dec 26 '21 at 15:26
  • No problem I got you haha. I just barely made an app doing all this stuff so it’s still fresh on my mind. – Trev347 Dec 26 '21 at 19:00