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

9.3 KiB
Raw Blame History

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,能力包括:

  • Consoleconsole.log/info/warn/error/trace 全部可见;可在控制台中直接 evaluate JS 表达式
  • Sources:查看 H5 包内所有 .js / .html / .css 源码;下断点、单步、Watch 表达式
  • Network:所有 XHR / fetch / 图片 / 字体请求,请求头/响应/Timing 全可见(含 file:// 本地资源)
  • ElementsDOM 树、计算后样式、动画检视
  • StoragelocalStorage / sessionStorage / Cookies / IndexedDB
  • TimelinesCPU / 渲染 / 网络时间线

与 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

补丁形态(两处一致):

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 异常堆栈。

支持直接在底部输入框运行表达式,例如:

window.WebViewJavascriptBridge          // 查看桥对象
typeof app_gameid                        // 查看预注入变量
bridge.callHandler('getphoneInfo', null, r => console.log(r))  // 触发桥调用

4.4 关闭 Web Inspector

直接关掉浮窗即可,不影响 app 运行。下次需要时重新打开。


5. 多 WebView 场景

本项目同时存在最多 3 个 WKWebView 实例:

场景 创建位置 何时存在
大厅 WebContainerViewControllerBridgedWebView App 全程
子游戏 SubGameViewControllerBridgedWebView 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 构建问题,原生侧无能为力

Q5:Network 标签里看到一堆奇怪的 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 输出:原生侧已经装了 H5ErrorRelaySource/Bridge/H5ErrorRelay.swift),会把 console.error / window.onerror / unhandledrejection 转发到原生 printDebug build 可在 Xcode 控制台看到。要扩展到 console.log 全量转发,可参考其实现照葫芦画瓢
  • 断点调试原生 Swift 与 H5 同时跑Xcode + Safari Web Inspector 同时打开,两边各自下断点互不影响

9. 修订记录

日期 内容
2026-06-24 文档建立。落地 BridgedWebView / OverlayViewController 两处 isInspectable 补丁。