3

My very simple program is looping through an array to export several files. While it's in the loop, I'd like it to update a text field to tell the user which file is currently exporting. Code looks like this:

for item in filesArray {
    var fileName = item["fileName"]

    fileNameExportLabel.stringValue = "Exporting \(fileName).ext"
    println("Exporting \(fileName).ext")

    //--code to save the stuff goes here--
}

What happens is: println works correctly, throwing out a message for each file, but the label called fileNameExportLabel is only updated when the last file has been exported, so it's blank during the whole loop and gets the last file name once the loop reaches the end.

Any Idea? I'm a total noob here, I'm wondering if the NSTextField needs a command to be updated, similarly to a table view.

Thanks in advance!

Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
Iacopo Boccalari
  • 1,195
  • 2
  • 12
  • 19

2 Answers2

6

Your loop is running on the main thread. The UI updates won't happen until your function finishes. Since this is taking a long time, you should do this on a background thread and then update the textfield on the main thread.

Try this:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    for item in filesArray {
        var fileName = item["fileName"]

        // Update the text field on the main queue
        dispatch_async(dispatch_get_main_queue()) {
            fileNameExportLabel.stringValue = "Exporting \(fileName).ext"
        }
        println("Exporting \(fileName).ext")

        //--code to save the stuff goes here--
    }
}
vacawama
  • 150,663
  • 30
  • 266
  • 294
  • Thanks a lot for your answer, it sounds more complex than I expected. I know nothing about multi threading, so I should probably give up and get back to this after I'll have some more experience. Or is it something relatively easy to achieve? – Iacopo Boccalari Jun 15 '14 at 14:48
  • It's not that hard, but I haven't done it in Swift yet. I'm looking for the right syntax. – vacawama Jun 15 '14 at 14:49
  • Your code works and the whole app is now responsive while exporting files. Thank you very much! – Iacopo Boccalari Jun 16 '14 at 06:49
2

This workt for me on Swift 4

DispatchQueue.global(qos: .default).async {
    for item in filesArray {
        var fileName = item["fileName"]

        // Update the text field on the main queue
        DispatchQueue.main.async {
            fileNameExportLabel.stringValue = "Exporting \(fileName).ext"
        }
        print("Exporting \(fileName).ext")

        //--code to save the stuff goes here--
    }
}
TresRRR
  • 105
  • 8