Is it possible to have an NSAlert show & wait for the result within a DispatchQueue.Global.Async ? Since it needs to be done on the main thread.
Replies
Sorry had async instead of "DispatchQueue.main.sync".
Sure. Just use a semaphore to block your current thread until the alert is dismissed.
Can use Semaphore.
But you can do differently.
I had this case:
- want to send a message
- only if a valid code has been entered.
So I had a func sendMessage()
In this func, I call getCodeAndSend
In getCodeAndSend,
-I create the Alert with a field to enter code
- In the OK button com, I can test the code and send the message if OK.
Here is an extract from the code (it is for IOS, but same pattern for OSX)
func getCodeAndSendl(l) -> Void {
var inputCode: String = "xxxx"
//1. Create the alert controller.
let alert = UIAlertController(title: "Authorization", message: "Enter your code", preferredStyle: .alert)
//2. Add the text field.
alert.addTextField(configurationHandler: { (textField) -> Void in
textField.placeholder = "0000"
textField.isSecureTextEntry = false // setting the secured text for using password
})
//3. Grab the value from the text field.
let yesAction = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
let textField = alert.textFields![0]
inputCode = textField.text!
let storedCode = UserDefaults.standard.string(forKey: plistCodeKey)
if inputCode == storedCode {
self.sendToWebServer()
} else {
// alert wrong code
let codeController = UIAlertController(title:"Wrong code.",
message: "", preferredStyle: UIAlertControllerStyle.alert)
let cancelAction = UIAlertAction(title: "OK!", style: UIAlertActionStyle.cancel, handler: nil)
codeController.addAction(cancelAction)
self.present(codeController, animated: true, completion: nil)
}
})
alert.addAction(yesAction)
// 4. Present the alert.
self.present(alert, animated: true, completion: nil)
}
Thanks for the reply but I don't see what it has to do with DispatchQueue ?
The main problem is that NSAlert needs to be done on the main thread and is executed within ".global(...).async { ... }". I knew something can be done on the main thread using ".main.async { ... }" but just missed using ".main.sync { ... }".
Can't you dispatch getCodeAndSend. to the main thread ?
Yes, thanks.
So, does it work now as you wish ?
If so, don't forget to close the thread.