PjotrC PjotrC - 5 months ago 74
Swift Question

Swift: How to let background thread wait for user input?

I have a background thread which needs some user input. Since it is not recommended to call an NSAlert window from a background thread, I like to do this in the main thread. But how can I let the background thread wait till the NSAlert window is closed?

let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
// some background task

dispatch_async(dispatch_get_main_queue()) {
// UI task asking for user input:
let alert = NSAlert()
alert.messageText = "Some text"
alert.informativeText = "Some information"
alert.addButtonWithTitle("Yes")
alert.addButtonWithTitle("No")
result = alert.runModal()
}

// some background task, treating user input (Yes/No)
}

Answer

You can use semaphore.

dispatch_async(dispatch_get_global_queue(priority, 0)) {
    // some background task

    //Create a semaphore with count = 0
    let semaphore = dispatch_semaphore_create(0)

    dispatch_async(dispatch_get_main_queue()) {
        // UI task asking for user input:
        let alert = NSAlert()
        alert.messageText = "Some text"
        alert.informativeText = "Some information"
        alert.addButtonWithTitle("Yes")
        alert.addButtonWithTitle("No")
        result = alert.runModal()
        //Signal semaphore
        dispatch_semaphore_signal(semaphore)
    }

    //Wait for semaphore
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
    // some background task, treating user input (Yes/No)
}

You should not "wait" in the main thread. But background threads are other things.