0

I am new to programming, and I have run into a situation where I think a completion handler would be helpful. But do not fully understand how they work, or how to write one.

I am trying to upload multiple images to firebase Storage, then once that is done, take the URLS created for those images and save them to the firebase Database. In my current code, the database function does not wait for the storage function to finish, so the array of URLS is empty when it sends it to the database.

So I have a button that when pressed needs to complete all these actions, then dismiss the view. Got rid of that bit because it is irrelevant now.

    @IBAction func saveNewAppointment(_ sender: Any) {
        self.storePhotos()
        self.postToDatabase()   
    }

func storePhotos() {
    for image in photosToShow {
        if let img = UIImageJPEGRepresentation(image, 0.2) {
            let imgUID = NSUUID().uuidString
            let metaData = FIRStorageMetadata()
            metaData.contentType = "image/jpef"
            DataService.ds.REF_CURRENT_USERS_PHOTOS.child(imgUID).put(img, metadata: metaData) { (metaData, error) in
                if error != nil {
                    print("IMAGE STORAGE ERROR", error ?? "")
                } else {
                    print("Successfully uploaded image to firebase storage")
                    let downloadURL = metaData?.downloadURL()?.absoluteString
                    self.imgURLs.append(downloadURL!)
                }

            }
        }
    }
}

func postToDatabase() {
    print("Posting Data")
    let date = appointment.dateToSave
    let formula = appointment.formulaToSave
    let appointmentToSave = ["date": date, "formula": formula]

    let clientID = appointment.clientID

    let appPhotoRef = DataService.ds.REF_CURRENT_USER_APPOINTMENTS.child(clientID).childByAutoId()
    appPhotoRef.setValue(appointmentToSave)


    for url in self.imgURLs {
        self.URLsToSave[url] = "True"
    }

    appPhotoRef.child("photoURLS").setValue(URLsToSave)

}

In my limited understanding, I need to wait for the first fuction to complete before calling the next one, postToDatabase.

Should storePhotos call postToDatabase itself... in a completion handler... or does it just pass a success object to postToDatabase, which tells it to run?

Any help greatly appreciated.

Math Engel
  • 83
  • 12
  • If you read this answer it might help you figure out how completion handler works http://stackoverflow.com/questions/24231680/loading-downloading-image-from-url-on-swift/27712427#27712427 – Leo Dabus Jan 31 '17 at 00:12
  • 1
    @LeoDabus cool, thanks! – Math Engel Jan 31 '17 at 00:16
  • Just a note: imageURLs should be an array of URLs not Strings. You need also to unwrap the optional URL `if let downloadURL = metaData?.downloadURL { imgURLs.append(downloadURL) } ` – Leo Dabus Jan 31 '17 at 00:27

0 Answers0