Reputation: 814
I have a really common problem trying to create spinning activity indicator during an user authentication task with Firebase
I tried to use CGD dispatch_async but that doesn't seem to handle my issue. Here is my code
@IBAction func SignMeIn(sender: AnyObject) {
ActivityIndicator.hidden = false
ActivityIndicator.startAnimating()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
NSLog("Before login func")
self.logIn()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSLog("After login func")
self.ActivityIndicator.stopAnimating()
self.ActivityIndicator.hidden = true
})
});
}
func logIn(){
myRootRef.authUser(TXT_User.text, password: TXT_Password.text,
withCompletionBlock: { error, authData in
if error != nil {
NSLog(error.debugDescription)
} else {
NSLog("Connected !")
}
})
}
The thing is I surely do something wrong since in debug mode appears in this order :
"Before login func"
"After login func"
"Connected !"
Whereas I should have
"Before login func"
"Connected !"
"After login func"
What am I doing wrong please ? Thank you very much for your help :) !
Upvotes: 0
Views: 125
Reputation: 923
Your problem is that you have 2 async tasks 1. Login completion block 2. Activity indicator stop
If you want to stop activity indicator after the login process you should move the code in the completion block like this
@IBAction func SignMeIn(sender: AnyObject) {
ActivityIndicator.hidden = false
ActivityIndicator.startAnimating()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
NSLog("Before login func")
self.logIn()
});
}
func logIn(){
myRootRef.authUser(TXT_User.text, password: TXT_Password.text,
withCompletionBlock: { error, authData in
if error != nil {
NSLog(error.debugDescription)
} else {
NSLog("Connected !")
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSLog("After login func")
self.ActivityIndicator.stopAnimating()
self.ActivityIndicator.hidden = true
})
})
}
Upvotes: 2
Reputation: 5554
The problem is that execution returns from logIn
immediately, and not when the completion block is called.
To do what you need, you have to make the call to the main queue within the logIn
completion handler - like this
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
NSLog("Before login func")
self.logIn()
}
func logIn(){
myRootRef.authUser(TXT_User.text, password: TXT_Password.text,
withCompletionBlock: { error, authData in
// success or fail, you need to stop the Activity Indicator
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSLog("After login func")
self.ActivityIndicator.stopAnimating()
self.ActivityIndicator.hidden = true
})
});
if error != nil {
NSLog(error.debugDescription)
} else {
NSLog("Connected !")
}
})
}
Upvotes: 2