pho_pho pho_pho - 4 months ago 21
Swift Question

Extract Value from Block Swift

I want to be able to use the the currentVote Int outside of the block, where currentVote is a variable defined at the top of the class.

databaseRef.child("Jokes").child(currentKey).observeSingleEventOfType(.Value, withBlock: { (snapshot) in

if let currentNumber = snapshot.value! as? [String: AnyObject] {

let currentValue = (currentNumber["votes"] as? Int)!

self.currentVote = currentValue


}

})

//*Location* where i want to use currentVote with it's new value


Location is where I want to use the value of currentVote. When i print the value here, i am returned nil, and thereafter I will be returned the expected value. When I print the value inside the block, I get the expected value. I understand why this is, it's because the block is being executed off the main thread and therefore when i print outside of the block, the print is being executed before the block and so it has a value of nil. I know that to get it onto the main thread you have to use

dispatch_async(dispatch_get_main_queue(), {
code
})


However, I have nested my code in numerous different ways with this dispatch call, but haven't been able to obtain the new value of currentVote. I have searched through stack overflow and users have suggested making a function outside of the block, then calling this inside. However, their function involves

func printValue(value: Int) {

print(value)

}


Which, as you can see would be useless to me as I want to use the value outside of the block, not print it!

***Code altered according to Cod3rite suggestion****

func get(completion: (value: Int) -> Void) {

databaseRef.child("Jokes").child(currentKey).observeSingleEventOfType(.Value, withBlock: { (snapshot) in

if let currentNumber = snapshot.value! as? [String: AnyObject] {

let currentValue = (currentNumber["votes"] as? Int)!

self.currentVote = currentValue

completion(value: self.currentVote!)

}

})

}

//where I want to use currentVote


I have put it into a completion as suggested, but I still don't know how to obtain the variable!

Answer

You almost got it right. But here are a little modifications you need to do:

func get(completion: (value: Int) -> Void) {

        databaseRef.child("Jokes").child(currentKey).observeSingleEventOfType(.Value, withBlock: { (snapshot) in

           if let currentNumber = snapshot.value! as? [String: AnyObject] {

              let currentValue = (currentNumber["votes"] as? Int)!
               completion(value: currentValue)

            }


        })

        }

Now when you want to call this get, do this:

get { value in
 //Now you have your value retrieved from firebase and you can use it however you want.
 print(value)
 self.currentVote = value
//your other code
}
Comments