Open File Dialog crashes in Swift
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.
NSOpenPanel/NSSavePanel crashes in Swift 3
Give your app access to user selected files under <Your Project> -> <Your Target> -> Capabilities -> App Sandbox -> File Access -> User Selected File
.
How to close System dialogs that appears on app crash?
You have two options:
- Use
InterruptionMonitor
(documentation, use-case). This
approach is however kinda old and I found, that it does not work for
all dialogs and situations. - Create a method, which will wait for some regular app's button. If the app's button (or tab bar or other such XCUIElement) is visible and hittable after your app started, you can proceed with your test and if it's not, you can wait for the
UserNotificationCenter
dialog's button and identify&tap it by its string/position.
I'm using the second approach and its working much better, than the InterruptionMonitor
. But it really depends on your app layout and use-case.
How do I get the file open dialog to work, when called through a SwiftUI WKWebView inside a macOS native app?
You have to implement the following WKUIDelegate
delegate method
/** @abstract Displays a file upload panel.
@param webView The web view invoking the delegate method.
@param parameters Parameters describing the file upload control.
@param frame Information about the frame whose file upload control initiated this call.
@param completionHandler The completion handler to call after open panel has been dismissed. Pass the selected URLs if the user chose OK, otherwise nil.
If you do not implement this method, the web view will behave as if the user selected the Cancel button.
*/
@available(OSX 10.12, *)
optional func webView(_ webView: WKWebView, runOpenPanelWith
parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping ([URL]?) -> Void)
Here is example of implementation
func webView(_ webView: WKWebView, runOpenPanelWith parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping ([URL]?) -> Void) {
let openPanel = NSOpenPanel()
openPanel.canChooseFiles = true
openPanel.begin { (result) in
if result == NSApplication.ModalResponse.OK {
if let url = openPanel.url {
completionHandler([url])
}
} else if result == NSApplication.ModalResponse.cancel {
completionHandler(nil)
}
}
}
Application crashing on launch
I re-generated the Distribution CERTIFICATE, and profile. THIS resolved the issue for me!
Related Topics
How to Add a Double Tap Gesture Recognizer in Swift
Vapor Toolbox Broken After Upgrading Swift
How to Succinctly Get the First 5 Characters of a String in Swift
Swift Protocol Generic as Function Return Type
Differences Between "Static Var" and "Var" in Swift
Realm Mobile Platform, How to Connect While Offline
Sending a Parameter Argument to Function Through Uitapgesturerecognizer Selector
How to Determine If a Variable Passed in Is Reference Type or Value Type
How to Make Firebase Database Data the Data Source for Uicollection View
Swiftui Onhover Doesn't Register Mouse Leaving the Element If Mouse Moves Too Fast
How to Move a Rotated Scnnode in Scenekit
Hstack with Sf Symbols Image Not Aligned Centered
How to Create Text File for Writing
Navigationview Doesn't Display Correctly When Using Tabview in Swiftui
How to Make Alphabetically Section Headers in Table View with a Mutable Data Source
How to Store a Reference to an Integer in Swift
Is It Possible in Swift to Add Variables to an Object at Runtime