I have trouble understanding how to properly using completion handlers, especially in relation to firebase code. As I understand it, the completion handler executes when the Fire Base has done it's thing asynchronously, right. So just to get a feel on how it works, I just want to use completion handlers to print "DONE" when the data has been gathered with FB.
I have tried the following code, but I obviously don't understand it as it doesn't work.
//PUTTING THE FB CODE IN FUNCTION
func test(completion: @escaping (String) -> Void) {
databaseRef.child(dataRecieverStringRecipeView!).observeSingleEvent(of: .value, with: {(snapshot) in
for item in snapshot.children.allObjects as! [DataSnapshot] {
let thisItem = item.value as! NSDictionary
let tempRecipe = Recipe()
tempRecipe.fbKey = item.key
tempRecipe.recipeHeaderObject = (thisItem["recipeHeaderFirebase"] as! String)
tempRecipe.recipeTextObject = (thisItem["recipeIngredientsTextFirebase"] as! String)
tempRecipe.recipeImageObject = (thisItem["recipeImageFirebase"] as! String)
self.recipeClassArray.append(tempRecipe) //ADD OBJECT TO ARRAY
}
}) //END LOOP
completion("DONE")
}//COMPLETION
test()//???Not sure what to do here...
答案 0 :(得分:1)
Completion handlers are basically WHEN statements.
When an event happens (for example receiving result of an api call), trigger completion().You can also pass values with this completion.
func test(completion: @escaping (_ message: String) -> Void) {
databaseRef.child(dataRecieverStringRecipeView!).observeSingleEvent(of: .value, with: {(snapshot) in
//you are inside a completion handler. this code executes WHEN you've received a snapshot object
// so you loop through and process the items
for item in snapshot.children.allObjects as! [DataSnapshot] {
let thisItem = item.value as! NSDictionary
let tempRecipe = Recipe()
tempRecipe.fbKey = item.key
tempRecipe.recipeHeaderObject = (thisItem["recipeHeaderFirebase"] as! String)
tempRecipe.recipeTextObject = (thisItem["recipeIngredientsTextFirebase"] as! String)
tempRecipe.recipeImageObject = (thisItem["recipeImageFirebase"] as! String)
self.recipeClassArray.append(tempRecipe) //ADD OBJECT TO ARRAY
}
// and its done here
completion("DONE")
})
}
// Now to use it...
// You need to pass in a completion handler varaible to your test function when calling it
test(completion: { message in
// WHEN you get a callback from the completion handler,
print(message)
})
答案 1 :(得分:1)
You need to pass a closure to your test()
method, like this:
test(completion: (status: String) -> Void {
print(status)
})
Or like this:
func completion(status: String) {
print(status)
}
test(completion: completion)
You could also use trailing closure syntax, since your closure is the last parameter:
test() { (status) in
print(status)
}