Design §3.7:补 WKUIDelegate alert / confirm 2 项接口

覆盖契约 §4.3 H5 alert(msg) / confirm(msg) 触发原生弹窗的硬约束。

WKWebView 默认行为是直接吞掉 H5 的 alert/confirm 不弹任何窗口,必须实现
WKUIDelegate 才有响应。不实现的代价:H5 业务里 alert("登录失败")
之类的提示用户完全看不见,业务哑火无可视化报错。

§3.7 实现骨架:
  - runJavaScriptAlertPanelWithMessage → UIAlertController .alert,
    标题 appDisplayName,单"确定"按钮,completionHandler() 必须调一次
  - runJavaScriptConfirmPanelWithMessage → "取消"/"确定" 两按钮,
    completionHandler(false/true) 必须调一次
  - 接入点:bridgedWebView.webView.uiDelegate = self 在 viewDidLoad
    与 navigationDelegate 一起设置

§3.7.1 与 msext 4 维度差异表(标题来源 / 按钮顺序 / 样式 / 并发)+
明示"未实现导致的现象"提醒,方便 1.17 真机联调时排查。

至此契约 §3 + §附录 A + §4.3 共 51 项接口(22 异步 handler + 15 反向 callback
+ 3 弹层 polyfill + 9 同步 getter polyfill + 2 WKUIDelegate)的 Design 实现
骨架全部覆盖完整。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
joywayer
2026-06-22 07:33:33 +08:00
co-authored by Claude Opus 4.7
parent 5f5f6a9ff9
commit 33574a1cc2
+72
View File
@@ -827,6 +827,78 @@ extension WebContainerViewController: WKNavigationDelegate {
- **Sentry 上报**:每次崩溃都打 breadcrumb,持续高崩溃率应该触发告警
- **大厅 / 子游戏 / 弹层都受这条覆盖**,因为它们都继承自 WebContainerViewController
### 3.7 WKUIDelegate alert / confirm(契约 §4.3
H5 用 `alert(msg)` / `confirm(msg)` 触发原生弹窗,WKWebView 默认行为是**直接吞掉不弹**——必须在容器 VC 上实现 `WKUIDelegate` 才能让 H5 业务的提示信息正常显示。这是契约 §4.3 的硬约束,**漏掉直接导致 H5 任何 alert/confirm 无响应**。
涉及 2 项接口(不在 §3.1 主表,单列):
1. `runJavaScriptAlertPanelWithMessage` — H5 调 `alert(msg)`
2. `runJavaScriptConfirmPanelWithMessage` — H5 调 `confirm(msg)` 期待返回 true/false
```swift
// Source/WebView/WebContainerViewController.swift WKUIDelegate
extension WebContainerViewController: WKUIDelegate {
// MARK: - §4.3 H5 alert(msg)
//
// BundleConfig.shared.appDisplayNamemsext gamehallname
// ""
// completionHandler WKWebView JS
public func webView(_ webView: WKWebView,
runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
let alert = UIAlertController(
title: appDisplayName,
message: message,
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "确定", style: .default) { _ in
completionHandler()
})
present(alert, animated: true)
}
// MARK: - §4.3 H5 confirm(msg)
//
// alert
// / completionHandler(true) / completionHandler(false)
// completionHandler bool
public func webView(_ webView: WKWebView,
runJavaScriptConfirmPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (Bool) -> Void) {
let alert = UIAlertController(
title: appDisplayName,
message: message,
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "取消", style: .cancel) { _ in
completionHandler(false)
})
alert.addAction(UIAlertAction(title: "确定", style: .default) { _ in
completionHandler(true)
})
present(alert, animated: true)
}
}
```
接入:`bridgedWebView.webView.uiDelegate = self``viewDidLoad``navigationDelegate` 一起设置。
#### 3.7.1 与原 msext 的差异
| 维度 | msext 现状 | 新外壳决策 |
|------|----------|---------|
| 标题文案 | `gamehallname` PCH 常量 | `appDisplayName`CFBundleDisplayName / CFBundleName,自包含) |
| confirm 按钮顺序 | "取消" 在左 / "确定" 在右 | 严格保持(iOS UIAlertController 默认 cancel 在左 + default 在右) |
| 弹窗样式 | UIAlertController + .alert | 同款 |
| 多帧并发 | msext 偶发"alert 串"叠加,体验略乱 | 当前同时只允许一个 alert(present 队列);如未来 H5 业务有真并发,再加 pendingAlertQueue |
> ⚠️ 不实现这两个方法的代价:H5 业务里 `alert("登录失败")` 之类的提示**用户完全看不见**,业务流程哑火无可视化报错。是 Phase 1.17 真机联调时最容易暴露的缺漏点,因此 §10 验收清单单列。
---
## 4. 启动流程重新设计