Reputation: 21
I'm a newcomer to Swift (2.2) and am having a problem with a simple app using Xcode 7.3 and OS X 10.11. In this app, the user clicks a button and selects a file through NSOpenPanel. The code uses the URL selected to get the file's data and name, then processes the data and saves the result somewhere else. With large files, the processing can take several seconds. When processing large files, once the file is selected, the space where the Open File window had been remains blank, covering the app view and everything else, and stays there until the operation is complete. Also, the app's outlets are frozen until the operation finishes. It appears NSOpenPanel isn't handing window control back to the app and the system.
The code goes like this:
@IBAction func processFile(sender: AnyObject) {
var chosenURL: NSURL?
let openPanel = NSOpenPanel()
openPanel.title = "Choose a file"
openPanel.canChooseDirectories = false
openPanel.allowsMultipleSelection = false
if openPanel.runModal() == NSFileHandlingPanelOKButton {
chosenURL = openPanel.URL
}
let dataBytes = NSData(contentsOfURL: chosenURL!)
let fileName = chosenURL!.lastPathCompnent!
// Remaining code processes dataBytes and fileName
I've tried a few variations but get the same result. Searching for "NSOpenPanel won't close" on the 'net usually just brings up examples in Objective-C, which I know nothing of. Any suggestions of how to make NSOpenPanel shut off and have view and control return to the app window?
Upvotes: 1
Views: 328
Reputation: 21
Following on from Eric D's suggestion, I looked into Grand Central Dispatch and background processes. My first approach was:
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) {
dataBytes = NSData(contentsOfURL: chosenURL!)
}
That didn't change anything. I found I had to put the whole remaining process (everything from 'let dataBytes…' onwards) within the dispatch closure, with 'dispatch_async(dispatch_get_main_queue())' statements around UI updates. This stopped the window from freezing and blanking, and returned control to the app. Thanks again, Eric.
Upvotes: 1