How do I use completion handlers in Fire Base

时间:2018-03-25 19:41:17

标签: swift firebase completionhandler

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...

2 个答案:

答案 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) }