Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - Why is DispatchGroup not working in this function?

I am waiting for idToken response before returning the variable.

Please don't tell me to just use completion handler and call it without a DispatchGroup. I know I can do that, but I am trying to understand why this logic does not work.

func createToken() -> String {
    
    var token = "empty"
    var group = DispatchGroup()
    group.enter()
    
    let currentUser = Auth.auth().currentUser
    
    currentUser?.getIDTokenForcingRefresh(true) { idToken, error in
        
        token = idToken ?? "error"
        print("Token Set")
        group.leave()
    }
    
    group.wait(timeout: DispatchTime.now() + 10)

    return token
}

Running:

print("create ")
print(createToken())
print("done")

Output:

create 
empty
done
Token Set
like image 200
Sam KC Avatar asked May 25 '26 01:05

Sam KC


1 Answers

If getIDTokenForcingRefresh dispatches its completion handler closure back to the main queue, you would see precisely the behavior you describe. When execution hits the wait call, it will block the main thread. But if the completion handler closure is being dispatched to the main queue, that will not be able to run until the wait call times out and the main thread is freed again.

You can confirm this thesis, that getIDTokenForcingRefresh is calling its completion handler on the main thread, in a variety of ways:

  • Try removing the timeout, in which case this code would completely deadlock if it was using the main queue/thread.

  • Print Thread.isMainThread.

  • Add a precondition statement:

    dispatchPrecondition(condition: .onQueue(.main))
    
  • Set a breakpoint in this closure and let the debugger tell you which thread was used.

But you are quite right: The wait pattern should be avoided in general.

like image 111
Rob Avatar answered May 27 '26 15:05

Rob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!