OK, let's assume the logic of your design is OK.
You call DispatchQueue.main.async : that probably means that other tasks as validation code run in another thread. EXACT ?
If so,
- you call the validation code in another thread
- then, the code in main thread continues immediately
- hence, result is not set correctly.
One way to handle this is to use some type of semaphore (in very simple way)
- define a global var semaphore that must be visible in IBAction and in validation code (you can define it out of a class, to have global scope)
- set semaphore to false before calling validation code
- in validation code, you will set semaphore to true when the validation has been checked (not depending on check OK or not OK)
- wait for semaphore before testing result
- of course that will block everything until user has entererd its code (you could also release semaphore after some time out, but that can be done in a second stage)
PS :
- I do not see either how you configure moc.performAndWait, but that should not change the logic
- what do you wait in moc.performAndWait ?
var semaphore = false // Global scope, must be visible in validation code
@IBAction func login(_ sender: UIButton) {
DispatchQueue.main.async {
semaphore = false
//call to validation code
someActivityIndicatorView.isHidden = false
someActivityIndicatorView.startAnimating()
repeat {//wait till semaphore is set true in validation code
} while !semaphore
if result == ok
moc.performAndWait {
moc.performAndWait {
moc.performAndWait {
loadAndSaveExternalDatabase()
}
loadAndSaveOtherExternalDatabase()
}
self.someActivityIndicatorView.stopAnimating()
let principalScreen = self.storyboard?.instantiateViewController(withIdentifier: "principalScreen")
self.addChildViewController(principalScreen!)
self.view.addSubview(principalScreen!.view)
principalScreen?.didMove(toParentViewController: self)
}
if result != ok
show alert with error
self.someActivityIndicatorView.stopAnimating()
self.someActivityIndicatorView.isHidden = true
}
}