Value of String won't change in Swift despite clear declaration [duplicate]
Clash Royale CLAN TAG#URR8PPP
Value of String won't change in Swift despite clear declaration [duplicate]
This question already has an answer here:
I am making an app in which I have to return a String representing the existence of a certain reference to my firebase realtime database (I am not using a Bool for other reasons). Despite executing the print commands directly above and below, when I print the function, the value of the String won't change and prints its default value "Unchanged".
My code:
func checkIfMovieHasAlreadyBeenShown(movieID: String) -> String
var hasItBeenSeen = "Unchanged"
let uid = Auth.auth().currentUser?.uid
let ref = Database.database().reference()
ref.child("Seen Movies").child(uid!).observeSingleEvent(of: .value, with: (snapshot) in
if snapshot.hasChild(movieID)
print("The Result:")
self.changeStringHasItBeenSeen(YNString: "yes")
print("YES")
else
print("The Result:")
self.changeStringHasItBeenSeen(YNString: "no")
print("NO")
)
return hasItBeenSeen
It is printed here:
print(checkIfMovieHasAlreadyBeenShown(movieID: "39"))
print(checkIfMovieHasAlreadyBeenShown(movieID: "38"))
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
return hasItBeenSeen
1 Answer
1
observeSingleEvent
is called in a closure. The return hasItBeenSeen
line will not be affected by anything in the closure, as it will return first.
observeSingleEvent
return hasItBeenSeen
Imagine this: you tell your friend to go buy some apples. Before he has even left, you ask him for the price. Of course, he won't know, because he hasn't gone to buy the apples yet.
You need some way of performing something AFTER the closure has been called (or after the apples have been bought). Usually this can be done with a completion handler, where you pass a closure into your checkIfMovieHasAlreadyBeenShown
function, such as, "do this AFTER you buy the apples".
checkIfMovieHasAlreadyBeenShown
Then you would call your function this way: checkIfMovieHasAlreadyBeenShown(movieID: "39", completion: seen in print(seen) )
checkIfMovieHasAlreadyBeenShown(movieID: "39", completion: seen in print(seen) )
Enjoyed the apple analogy.
– matt
Aug 6 at 2:57
@Schemetrical's answer is indeed the problem: when your
return hasItBeenSeen
runs, the value hasn't been loaded yet. Also see: stackoverflow.com/questions/43854811/…, stackoverflow.com/questions/43823808/…, stackoverflow.com/questions/41262793/…, stackoverflow.com/questions/42894472/…– Frank van Puffelen
Aug 6 at 2:54