user21955191
user21955191

Reputation: 39

Use different types of javascript alerts in macOS WebView based app

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
            }
        }
    }

Upvotes: 1

Views: 45

Answers (1)

user21955191
user21955191

Reputation: 39

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)
    }
}

Upvotes: 1

Related Questions