You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在macOS WebView应用中用NSAlert实现JS弹窗(Alert/Confirm/Prompt)

macOS 下用 NSAlert 实现 WKWebView JS 弹窗(Alert/Confirm/Prompt)

直接替换iOS端UIAlertController的实现逻辑,对应WKUIDelegate的三个核心方法,以下是适配macOS的完整代码:

1. JS Alert 弹窗实现

对应 webView(_:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:) 方法:

func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
    let alert = NSAlert()
    alert.messageText = message
    alert.addButton(withTitle: "确定")
    // macOS要求主线程弹窗,避免线程异常
    DispatchQueue.main.async {
        alert.runModal()
        completionHandler()
    }
}

2. JS Confirm 弹窗实现

对应 webView(_:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:) 方法:

func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
    let alert = NSAlert()
    alert.messageText = message
    alert.addButton(withTitle: "确定")
    alert.addButton(withTitle: "取消")
    
    DispatchQueue.main.async {
        let result = alert.runModal()
        // 第一个添加的按钮对应alertFirstButtonReturn,第二个对应alertSecondButtonReturn
        completionHandler(result == .alertFirstButtonReturn)
    }
}

3. JS Prompt 弹窗实现

对应 webView(_:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:) 方法,这部分是和iOS差异最大的地方:

func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
    let alert = NSAlert()
    alert.messageText = prompt
    alert.addButton(withTitle: "确定")
    alert.addButton(withTitle: "取消")
    
    // 手动创建输入框并绑定到alert的accessoryView
    let inputField = NSTextField(frame: NSRect(x: 0, y: 0, width: 300, height: 24))
    inputField.stringValue = defaultText ?? ""
    alert.accessoryView = inputField
    
    DispatchQueue.main.async {
        let result = alert.runModal()
        completionHandler(result == .alertFirstButtonReturn ? inputField.stringValue : nil)
    }
}

常见问题修正点

  • 必须在主线程调用runModal():macOS的NSAlert强制要求主线程展示,否则会出现弹窗无响应或崩溃,务必用DispatchQueue.main.async包裹弹窗逻辑。
  • 按钮返回值判断:NSAlert的按钮添加顺序决定返回值,第一个按钮对应.alertFirstButtonReturn,第二个对应.alertSecondButtonReturn,别搞混顺序。
  • Prompt输入框适配:macOS没有addTextField()方法,必须手动创建NSTextField并赋值给accessoryView,同时要设置合理的宽高保证显示正常。

内容的提问来源于stack exchange,提问作者user21955191

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 01:37:40