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.