Reputation: 23
Im trying to run some code after firebase has finished its downloading/uploading (eg segue or refresh)
for eg
I have x3 save functions which all have code to update both storage and database of certain data (eg text and images)
save1()
save2()
save3()
when an IBAction is performed I would like these functions to run, and on completion if their is no error to perform another function on completion (segue or refresh)
these 3 save function currently work within the IBAction
@IBAction func saveTap(_ sender: Any) {
save1()
save2()
save3()
}
Save function as follows:
(I check if image has been changed, then upload process begins)
func save1(){
if image1.image == nil {
let gender = userGender.text
self.databaseRef.child("users").child(gender!).child(Auth.auth().currentUser!.uid).child("images").child("imageOne").removeValue { (error, ref) in
if error != nil {
print(error!)}
}
let imageRef = self.storage.child(Auth.auth().currentUser!.uid).child("image1")
imageRef.delete { error in
if let error = error {
print(error)
} else {
print("Photo 1 image deleted")}
}
} else {
//Firebase child references
let profileImageRef = storage.child(Auth.auth().currentUser!.uid).child("image1")
let metaData = StorageMetadata()
metaData.contentType = "image1/jpeg"
//Firebase child references
//change uiimageview to uiimage for upload
guard let image = image1.image else
{return}
//change uiimageview to uiimage for upload
//Send to firebase storage
profileImageRef.putData(image.jpegData(compressionQuality: 0.1)!, metadata: metaData) { (data, error) in
if error == nil
{print("Photo 1 uploaded to storage")}
else
{print(error?.localizedDescription as Any)}}
//Send to firebase storage
//Update firebase database
profileImageRef.downloadURL(completion: { (url, error) in
if error != nil{
print(error!)
return}
if let profilePhotoUrl = url?.absoluteString{
let newValuesForProfile = profilePhotoUrl
let gender = self.userGender.text
self.databaseRef.child("users").child(gender!).child(Auth.auth().currentUser!.uid).child("images").child("imageOne").setValue(newValuesForProfile, withCompletionBlock: { (error, ref) in
if error != nil{
print(error!)
return}
print("Photo 1 updated in database")})}})
//Update firebase database
}
I need the uploads to complete before the segues are performed as the next view will be refreshing to the saved data that i'm trying to upload.
any help would be great, been at this for weeks now :( iv tried completion handlers but no luck as of yet.
thank you in advance
Upvotes: 0
Views: 96
Reputation: 844
You can check if the changes are saved with .childChanged somehow like this:
save1()
save2()
save3()
let ref: DatabaseReference!
ref = /YourDirectDatabaseReferenceForTheChangedNode/
ref.observe(.childChanged, with: {(snaphost) -> Void in
}
})
Maybe you should use UIActivityIndicatorView aswell to show something is going in the background.
@IBAction func saveTap(_ sender: Any) {
save1()
save2()
save3()
let activity: UIActivityIndicatorView = UIActivityIndicatorView()
activity.center = self.view.center
activity.hidesWhenStopped = true
activity.activityIndicatorViewStyle = .whiteLarge
self.view.addSubview(activity)
let ref: DatabaseReference!
ref = /YourDirectDatabaseReferenceForTheChangedNode/
ref.observe(.childChanged, with: {(snaphost) -> Void in
activity.stopAnimating()
if UIApplication.shared.isIgnoringInteractionEvents {
UIApplication.shared.endIgnoringInteractionEvents()
}
self.performSegue(withIdentifier: "backhome", sender: self)
}
})
}
Replace /YourDirectDatabaseReferenceForTheChangedNode/ with the correct child (what should change after save).
Upvotes: 0
Reputation: 100503
I think dispatchGroup
fits with your case
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
save1 { dispatchGroup.leave() }
dispatchGroup.enter()
save2 { dispatchGroup.leave() }
dispatchGroup.notify(queue: .main) {
self.perFormSegue//////
}
//
// e.x structure
func save1(completion:@escaping()->()) {
firesCallBack {
if success {
completion()
}
}
}
Upvotes: 2