I would like to use the open file dialogs from NSFilemanager but my code crashes sometimes and sometimes works and I do not know why. Sometimes it works 100%, sometimes the
The restrictions of the User Interface (UI) Calls, which are not Thread-Save, can be solved, when you use the following code, which executes a block of commands in the main thread asynchronously:
dispatch_async(dispatch_get_main_queue())
{
// This commands are executed ansychronously
}
So you have to write your own functions for every built-in-function, which is not thread-save like this (example with the open file dialog):
func not (b: Bool) -> Bool
{
return (!b)
}
func suspendprocess (t: Double)
{
var secs: Int = Int(abs(t))
var nanosecs: Int = Int(frac(abs(t)) * 1000000000)
var time = timespec(tv_sec: secs, tv_nsec: nanosecs)
let result = nanosleep(&time, nil)
}
func openfiledialog (windowTitle: String, message: String, filetypelist: String) -> String
{
var path: String = ""
var finished: Bool = false
suspendprocess (0.02) // Wait 20 ms., enough time to do screen updates regarding to the background job, which calls this function
dispatch_async(dispatch_get_main_queue())
{
var myFiledialog: NSOpenPanel = NSOpenPanel()
var fileTypeArray: [String] = filetypelist.componentsSeparatedByString(",")
myFiledialog.prompt = "Open"
myFiledialog.worksWhenModal = true
myFiledialog.allowsMultipleSelection = false
myFiledialog.canChooseDirectories = false
myFiledialog.resolvesAliases = true
myFiledialog.title = windowTitle
myFiledialog.message = message
myFiledialog.allowedFileTypes = fileTypeArray
let void = myFiledialog.runModal()
var chosenfile = myFiledialog.URL // Pathname of the file
if (chosenfile != nil)
{
path = chosenfile!.absoluteString!
}
finished = true
}
while not(finished)
{
suspendprocess (0.001) // Wait 1 ms., loop until main thread finished
}
return (path)
}
Please note, that the block is called asynchronously, that means you have to check, if the block has been processed and is finished or not. So I add a boolean variable "finsihed" which shows, when the block reaches its end. Without this you do not get the pathname but only an empty string.
If you are interested, I will post my savefiledialog-function, too. Please leave a comment if so.
Most of the User Interface (UI) Calls are not Thread-Save, that means that they only work without crash and unusual behaviour in the main-thread.
This is the problem with NSOpenPanel Calls, too. When calling from the main-thread everything is OK.