Files
youle_app_ios_v2/docs/H5-Debug-Guide.md
T
joywayerandClaude Opus 4.7 800497fd18 新增 H5-Debug-Guide:Safari Web Inspector 调试 H5 控制台的操作手册
整理大厅 / 子游戏 / 弹层三处 WKWebView 的 isInspectable 启用条件、
Mac Safari 与真机端开关、多 WebView 排查思路(Develop 菜单不刷新等
常见坑),并在 CLAUDE.md 文档索引登记。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 21:37:09 +08:00

213 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# H5 调试指南(Safari Web Inspector
> **定位**:本文档面向开发者,描述开发期调试 H5(大厅 / 子游戏 / 弹层)网页输出的标准方法。
>
> **适用范围**:仅 Debug 编译;Release 包不受影响(详见 §6 安全性说明)。
>
> **不在本文档范围内**
> - 桥接接口契约 → `H5-Native-Contract.md`
> - 业务功能验收清单 → `Verification-Checklist.md`
> - 原生 `os.log` 日志查看(直接看 Xcode 底部输出窗口即可)
---
## 1. 原理与适用范围
WebKit 自 iOS 16.4 起把 `WKWebView` 的网页检查器开关收敛到了 `isInspectable` 属性,**默认关闭**。打开后,该 `WKWebView` 加载的页面会被 Mac Safari 的"开发"菜单识别为可调试目标,等价于在浏览器里按 F12 打开 DevTools,能力包括:
- **Console**`console.log/info/warn/error/trace` 全部可见;可在控制台中直接 `evaluate` JS 表达式
- **Sources**:查看 H5 包内所有 .js / .html / .css 源码;下断点、单步、Watch 表达式
- **Network**:所有 XHR / fetch / 图片 / 字体请求,请求头/响应/Timing 全可见(含 `file://` 本地资源)
- **Elements**DOM 树、计算后样式、动画检视
- **Storage**localStorage / sessionStorage / Cookies / IndexedDB
- **Timelines**CPU / 渲染 / 网络时间线
**与 Xcode 控制台关系**Safari Web Inspector 看的是 H5 网页里的 console(JS 端运行结果);Xcode 控制台看的是原生 Swift `print` / `os.log` 输出。两者互补。
---
## 2. 工程内的代码改动(已落地,无需重做)
代码侧已经在两处 `WKWebView` 创建点加好了 `#if DEBUG` 守卫的 inspectable 开关:
- `ylgamehall/Source/WebView/BridgedWebView.swift` :大厅 / 子游戏共用的 `WKWebView`
- `ylgamehall/Source/WebView/OverlayViewController.swift` :弹层(msext `threeView` 等价容器)的 `WKWebView`
补丁形态(两处一致):
```swift
let webView = WKWebView(frame: .zero, configuration: configuration)
#if DEBUG
if #available(iOS 16.4, *) {
webView.isInspectable = true
}
#endif
```
**重要约束**
- **`#if DEBUG` 守卫不可去除** —— Release 包绝对不能让生产 IPA 暴露 Web Inspector,避免被外部审阅 JS 源码 / Storage / 注入表达式
- **`@available(iOS 16.4, *)` 兼容守卫不可去除** —— 本项目最低 iOS 15.6,低于 16.4 的设备走 `else` 分支(即不开启 inspectable),新设备才走真路径
- 新增任何第 4 个 `WKWebView` 创建点时,**同样补这 6 行**,否则该 WebView 在 Safari 里看不到
---
## 3. 前置准备
### 3.1 Xcode 端
确认 Scheme Run 配置是 Debug(默认就是):
- 菜单 **Product → Scheme → Edit Scheme...**`⌘<`)→ 左侧 **Run** → 右侧 **Info** 标签页
- **Build Configuration = Debug** ✅
### 3.2 Mac Safari 端(一次性)
1. Safari 顶部 → **Safari → 设置(`⌘,`)→ 高级**
2. 勾选最下方 **"在菜单栏中显示开发菜单"**
3. 关闭设置窗口,菜单栏出现"开发"项
### 3.3 真机端(一次性,仅真机需要;模拟器跳过)
iPhone 上:**设置 → Safari → 高级 → 网页检查器 = 开**。
> ⚠️ 这个"网页检查器"开关与 Safari 浏览器自身的网页检查无关,是 iOS 18+ 起 Apple 把 `WKWebView` 的可检视性也纳入了这个开关。**如果不开,Mac Safari 的"开发"菜单里看不到该设备的 H5 页面。**
---
## 4. 标准操作流程
### 4.1 启动 Debug build
1. Xcode 顶部 device picker → 选择目标设备/模拟器
2. `⌘R` 启动
3. 等大厅 H5 加载完成(屏幕上看到大厅 UI)
### 4.2 打开 Web Inspector
Mac Safari 顶部菜单 → **开发 → [设备名] → [页面标题或 URL]** → Web Inspector 浮窗弹出。
- 模拟器:菜单层级类似 `开发 → Simulator iPhone 16 Pro → file:///.../index.html`
- 真机:`开发 → 你的 iPhone 名字 → file:///.../index.html`
### 4.3 看 console 输出
Web Inspector 顶部 tab → **Console** → 实时显示 H5 端的 `console.*` 输出 + JS 异常堆栈。
支持直接在底部输入框运行表达式,例如:
```js
window.WebViewJavascriptBridge // 查看桥对象
typeof app_gameid // 查看预注入变量
bridge.callHandler('getphoneInfo', null, r => console.log(r)) // 触发桥调用
```
### 4.4 关闭 Web Inspector
直接关掉浮窗即可,不影响 app 运行。下次需要时重新打开。
---
## 5. 多 WebView 场景
本项目同时存在最多 3 个 `WKWebView` 实例:
| 场景 | 创建位置 | 何时存在 |
|------|---------|---------|
| 大厅 | `WebContainerViewController``BridgedWebView` | App 全程 |
| 子游戏 | `SubGameViewController``BridgedWebView` | push 进子游戏后,pop 销毁 |
| 弹层 | `OverlayViewController` 自建 `WKWebView` | present 显示中,dismiss 销毁 |
Safari "开发" 菜单会把每个**已加载页面**的 `WKWebView` 列为**独立一项**。
### 5.1 关键 gotchaDevelop 菜单不会自动刷新 ⭐
进入子游戏 / 打开弹层之后,**已经展开过的"开发"菜单不会自动刷新**,新出现的 WebView 不会冒出来。
**做法**
- 子游戏 push / 弹层 present 完成后
- 回 Mac,**先点其它菜单**(如 文件、编辑),让"开发"菜单收起
- 再展开 **开发 → [设备名]** → 此时新 WebView 才会列出来
### 5.2 多条目区分
如果列表里多个条目 `<title>` 相同 / 都显示为 `file://...index.html`,分不清哪个是哪个:
- **鼠标 hover 每个条目** → iPhone/模拟器屏幕上对应的 `WKWebView` 会**高亮蓝色边框**
- 用这个方法定位到目标 WebView,再点击进入
### 5.3 弹层 dismiss 后条目消失
弹层关闭后 `OverlayViewController` 释放,其 `WKWebView` 被回收,菜单条目随之消失。**必须在弹层显示着的时候调试**,关掉就来不及了。
---
## 6. 安全性 / Release 包说明
- `#if DEBUG` 守卫保证只有 Xcode 的 Debug 配置启用 `isInspectable = true`
- 渠道分发 / 企业签包都用 Release 配置 → 编译期就把 inspectable 那 5 行剔除 → 生产 IPA 没有任何"可检视性"信号
- 即便用户的 iPhone 开了"网页检查器"开关、Mac Safari 也开了"开发"菜单,Release 包的 WebView **依然不会出现在"开发"菜单**
- 因此**生产环境无需任何额外清理动作**,提交前也不用手动关任何开关
---
## 7. 常见问题 FAQ
### Q1Mac Safari "开发"菜单里完全看不到我的设备
按概率排查:
1. **菜单本身没开** → §3.2 把"在菜单栏中显示开发菜单"勾上
2. **真机未开"网页检查器"** → §3.3 设置 → Safari → 高级
3. **真机未连线 / 未信任电脑** → 数据线重插、iPhone 上重新点"信任"
4. **跑的不是 Debug build** → §3.1 Scheme → Run → Build Configuration = Debug
5. **iOS 版本 < 16.4** → 不支持,换个新设备 / 模拟器
6. **Mac 与 iPhone 不在同一 Wi-Fi** → 仅无线调试需要;有线优先
7. **`isInspectable` 补丁丢了** → grep `isInspectable` 应该有 2 处命中,否则被回滚了
### Q2:只看到大厅,子游戏 / 弹层看不到
→ §5.1 关闭"开发"菜单再重开。99% 是这个原因。
### Q3:能看到条目但 Console 是空的
可能原因:
- H5 端确实没有 `console.*` 调用(业务在沉默运行,没问题就不输出)
- Web Inspector 打开前的旧日志没被记录 → 在 Web Inspector 已经打开的状态下**触发一次** H5 操作(点按钮、切 tab)再看
- Console 顶部过滤器把日志级别过滤掉了 → 确认 All Levels 都选中
### Q4Sources 里看不到 .js 源码
- 检查 H5 zip 是否在沙盒里正常解压(`AppDataWriter.swift` 写入的 `app_*.js` 也应出现)
- 如果某文件被打包成 minified / 不带 sourcemap,源码可读性差 —— 这是上游 H5 构建问题,原生侧无能为力
### Q5Network 标签里看到一堆奇怪的 `wkbridge://__bridge_loaded__` 请求
这是 `WebViewJavascriptBridge` JS 端用 iframe + `src` 协议触发原生回调的机制,**正常行为,不要去掉**。详见 `Resources/JS/WebViewJavascriptBridge.js`
### Q6Safari 提示 "Web Inspector cannot connect"
- 重连数据线 / 重启 Safari / 重启 Xcode
- iPhone 16+ 偶发协议握手失败,重启 iPhone 通常恢复
---
## 8. 何时本方法不够用
Safari Web Inspector 是开发期主力,但有它够不到的场景:
- **真机 + 用户已在生产环境**Release 包没有 inspectable;需要的是事后日志,参考原生侧的崩溃 / 错误上报(项目目前无 crash 监控,依赖用户反馈)
- **断网 / 弱网下的 H5 表现**:用 Mac 上的 Network Link Conditioner,或模拟器 Features → Network Link Conditioner
- **生产环境的 H5 console 输出**:原生侧已经装了 `H5ErrorRelay``Source/Bridge/H5ErrorRelay.swift`),会把 `console.error / window.onerror / unhandledrejection` 转发到原生 `print`Debug build 可在 Xcode 控制台看到。要扩展到 `console.log` 全量转发,可参考其实现照葫芦画瓢
- **断点调试原生 Swift 与 H5 同时跑**Xcode + Safari Web Inspector 同时打开,两边各自下断点互不影响
---
## 9. 修订记录
| 日期 | 内容 |
|------|------|
| 2026-06-24 | 文档建立。落地 `BridgedWebView` / `OverlayViewController` 两处 `isInspectable` 补丁。 |