Use different types of javascript alerts in macOS WebView based app

41 views Asked by At

I'm creating WEB based app, running native on macOS, using embedded local HTML, JS and CSS files. I was before working with iOS and for similar purpose, I was using code bellow for presenting javascript alerts (alert type: alert, confirm and prompt) in WebView.

How to covert code bellow using NSAlert for macOS?

Here is the code I used for iOS:

extension ViewController: WKUIDelegate {
    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping () -> Void) {
        
        let alertController = UIAlertController(title: nil, message: message, preferredStyle: UIAlertController.Style.alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
            completionHandler()
        }))
        present(alertController, animated: true, completion: nil)
    }
    
    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping (Bool) -> Void) {
        
        let alertController = UIAlertController(title: nil, message: message, preferredStyle: UIAlertController.Style.alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
            completionHandler(true)
        }))
        alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
            completionHandler(false)
        }))
        present(alertController, animated: true, completion: nil)
    }
    
    func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping (String?) -> Void) {
        
        let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: UIAlertController.Style.alert)
        alertController.addTextField { (textField) in
            textField.text = defaultText
        }
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
            if let text = alertController.textFields?.first?.text {
                completionHandler(text)
            } else {
                completionHandler(defaultText)
            }
        }))
        alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
            completionHandler(nil)
        }))
        present(alertController, animated: true, completion: nil)
    }
}

This is the code I tried to implement in each function, but I don't know how to change it to work as the one build using UIAlertController.

    let alertController = NSAlert()
    alertController.messageText = message
    alertController.addButton(withTitle: "OK")
    alertController.addButton(withTitle: "Cancel")
    if let window = view.window {
        alertController.beginSheetModal(for: window) { modalResponse in
            alertController.window.close()
            switch modalResponse.rawValue {
            case 1001: // Exit
                exit(0)
            default: // Continue
                return
            }
        }
    }
1

There are 1 answers

1
user21955191 On

For everyone who need to show javascript alert using NSAlert(), here is solution:

extension ViewController: WKUIDelegate {
    func webView(_ webView: WKWebView,
                 runJavaScriptAlertPanelWithMessage message: String,
                 initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping () -> Void) {
        
            // Set the message as the NSAlert text
        let alert = NSAlert()
        alert.informativeText = message
        alert.addButton(withTitle: "Ok")
        
            // Display the NSAlert
        alert.runModal()
        
            // Call completionHandler
        completionHandler()
    }
    
    func webView(_ webView: WKWebView,
                 runJavaScriptConfirmPanelWithMessage message: String,
                 initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping (Bool) -> Void) {
        
            // Set the message as the NSAlert text
        let alert = NSAlert()
        alert.informativeText = message
        
            // Add a confirmation button “OK”
            // and cancel button “Cancel”
        alert.addButton(withTitle: "OK")
        alert.addButton(withTitle: "Cancel")
        
            // Display the NSAlert
        let action = alert.runModal()
        
            // Call completionHandler with true only
            // if the user selected OK (the first button)
        completionHandler(action == .alertFirstButtonReturn)
    }
    
    func webView(_ webView: WKWebView,
                 runJavaScriptTextInputPanelWithPrompt prompt: String,
                 defaultText: String?,
                 initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping (String?) -> Void) {
        
            // Set the prompt as the NSAlert text
        let alert = NSAlert()
        alert.informativeText = prompt
        alert.addButton(withTitle: "Submit")
        
            // Add an input NSTextField for the prompt
        let inputFrame = NSRect(
            x: 0,
            y: 0,
            width: 300,
            height: 24
        )
        
        let textField = NSTextField(frame: inputFrame)
        textField.placeholderString = (defaultText)
        alert.accessoryView = textField
        
            // Display the NSAlert
        alert.runModal()
        
            // Call completionHandler with
            // the user input from textField
        completionHandler(textField.stringValue)
    }
}