Skip to content

[Bug] 真机测试下 WebView 页面持续闪烁、Pencil 批注失效、双指手势行为异常及语音转文字不可用 #1

Description

@zls233

背景

项目:TouchCode

当前在真机测试中,设备已经可以正常完成配对,但进入实际交互后存在多个严重问题,主要集中在 WKWebView、Pencil 批注层、双指手势以及语音转文字功能。

目前应用可以启动和配对,但核心交互基本不可用。

当前现象

1. 页面无法稳定显示,持续闪烁

配对完成后,页面不能正常稳定显示,WKWebView / WebContent 似乎在不断重建、崩溃或重新拉起。

表现为:

  • 页面持续闪烁
  • WebView 内容无法稳定停留
  • 日志持续高速刷屏
  • 可以看到大量不同 PID 的 WebContent 进程不断出现
  • 随后又出现 Failed to terminate process / No such process found
  • 整体很像 WebContent 进程不断创建、退出、重启

日志中大量重复出现:

WebContent[...] Couldn't open <private> due to No such file or directory
WebContent[...] Couldn't open <private> due to Permission denied

Error acquiring assertion:
RBSServiceErrorDomain Code=1
target ... doesn't have entitlement
com.apple.developer.web-browser-engine.rendering
com.apple.developer.web-browser-engine.networking
com.apple.developer.web-browser-engine.webcontent

ProcessAssertion::acquireSync Failed to acquire RBS assertion
'XPCConnectionTerminationWatchdog'

Failed to terminate process:
RBSRequestErrorDomain Code=3 "No such process found"

还伴随:

WebContent[...] Request for application info error:
NSOSStatusErrorDomain Code=-10814

这个问题目前优先级最高,因为页面持续闪烁会直接导致后续 Pencil、手势等功能无法正常工作。


2. Pencil 无法正常在页面上批注

当前 Apple Pencil 无法稳定地在网页上进行批注。

预期:

  • Pencil 输入由批注层接管
  • 手指仍然可以正常滚动和缩放网页
  • Pencil stroke 应绑定到网页内容坐标
  • 网页滚动后批注位置仍然与原内容保持一致

实际:

  • Pencil 无法正常完成批注
  • 页面闪烁期间批注层/网页状态疑似反复被重置
  • Pencil 交互目前无法正常使用

需要重点确认:

  • PKCanvasView / 自定义 overlay 是否跟随 WebView 被重复创建
  • PencilKit overlay 生命周期是否稳定
  • WebView 刷新时是否错误重建批注层
  • Pencil 和 WebView 的 gesture recognizer 是否互相抢占
  • 批注层是否真的使用网页内容坐标,而不是屏幕坐标

3. 双指按住组件会跟随手指移动

当前设计是:

双指静止按住一段时间后触发语音输入组件。

预期行为:

  1. 双指按住约 0.45 秒
  2. 达到阈值后,在触发位置显示语音组件
  3. 组件出现后应固定在触发时的位置
  4. 后续手指轻微移动不应该让组件跟随移动
  5. 用户松开或完成操作后再结束该状态

当前实际行为:

  • 组件出现后仍会跟随双指移动
  • 视觉上像组件被绑定到了实时 touch location
  • 没有在进入 .voiceActive 状态时冻结 anchor point

建议进入语音状态的一瞬间保存:

voiceAnchorPoint = currentTwoFingerCenter

之后 UI 永远使用 voiceAnchorPoint,不要继续使用实时 touch center。


4. 双指左右滑应触发两侧按钮操作

需要补充/修正双指手势状态机。

预期:

  • 双指向左滑:触发左侧按钮对应操作
  • 双指向右滑:触发右侧按钮对应操作
  • 左右滑应与“双指静止按住进入语音”互斥
  • 一旦检测到明显水平移动,就不应该再进入语音模式

建议逻辑:

双指开始
   ↓
记录 initialCenter
   ↓
移动距离很小
   ├─ 持续 0.45s → Voice
   │
   └─ 水平位移超过 threshold
         ├─ dx < 0 → Left Action
         └─ dx > 0 → Right Action

同时:

  • 如果已经发生明显滚动/缩放,则此次语音长按应失败
  • 一旦进入 swipe 状态,不再允许进入 voice 状态
  • 一旦进入 voice 状态,组件位置固定,不再追踪 touch

5. 语音转文字目前无法正常使用

当前语音输入流程无法正常完成语音转文字。

需要检查完整链路:

双指长按
→ 开始录音
→ AVAudioSession
→ Speech 权限
→ SFSpeechRecognizer
→ recognitionTask
→ partial/final transcript
→ 更新 UI
→ 发送给 Codex / Bridge

需要确认:

  • NSMicrophoneUsageDescription
  • NSSpeechRecognitionUsageDescription
  • 麦克风权限是否成功授权
  • Speech Recognition 权限是否成功授权
  • AVAudioSession 是否正确 activate
  • 是否创建并持有 SFSpeechRecognitionTask
  • recognition task 是否被过早释放
  • 手势结束时是否错误地立即 stop/cancel
  • 真机上 recorder / audio engine 是否真的启动
  • 是否存在 WebView / UI 重建导致语音对象被销毁

日志中的其他异常

Keyboard Auto Layout constraint 冲突

日志中出现:

Unable to simultaneously satisfy constraints.

其中关键冲突:

'TUIKeyplane.height'
TUIKeyboardContentView.height == 251

'UIView-Encapsulated-Layout-Height'
UIView.height == 248

UIKit 最终主动 break:

TUIKeyplane.height

这看起来主要属于系统键盘内部约束冲突,目前不是页面闪烁的第一嫌疑,但需要观察是否由频繁 first responder 切换触发。


System Gesture Gate 超时

Gesture: System gesture gate timed out.

这个和当前自定义双指手势存在较强相关性,需要重点排查:

  • gesture recognizer 是否长时间停留在 .possible
  • 是否阻塞系统 gesture arbitration
  • 是否同时拦截 WebView scroll / pinch
  • 是否在主线程做同步耗时操作

Reporter / Fence timeout

Reporter disconnected
fence tx observer ... timed out after 0.600000

可能是 UI / rendering pipeline 在频繁重建或卡顿后的次生症状。


UAF / linguisticdata / boot UUID

Failed to get kern.bootsessionuuid
Current boot UUID is empty
com.apple.linguisticdata

目前看更像系统内部日志,优先级较低,不应作为主问题处理。


预期结果

真机上应该达到:

  1. 配对后 WebView 页面稳定显示,不再闪烁
  2. WebContent 进程不再不断生成/退出
  3. Apple Pencil 可以直接在网页上正常批注
  4. 批注位置绑定网页内容坐标
  5. 手指仍可以滚动和缩放网页
  6. 双指静止约 0.45 秒后进入语音模式
  7. 语音组件出现后固定在触发位置,不跟随手指移动
  8. 双指左滑触发左侧按钮
  9. 双指右滑触发右侧按钮
  10. swipe / scroll / pinch / voice 几种状态之间互斥
  11. 语音转文字可以在真机正常工作

建议排查优先级

P0:先解决 WebView 持续闪烁 / WebContent 重启

这是当前最核心问题。

重点检查:

  • WKWebView 是否被 SwiftUI body / updateUIView 不断重新创建
  • WKWebViewConfiguration 是否重复创建
  • 是否反复执行 load(...)
  • 是否频繁修改 WebView identity / .id(...)
  • UIViewRepresentable 的 Coordinator 生命周期
  • navigation failure / web content process termination 回调
  • 是否在 webViewWebContentProcessDidTerminate 中立即 reload,形成死循环
  • 是否因为开发服务器/HMR导致页面无限 reload
  • 是否同时存在多个 WKWebView 实例
  • WebView 是否在 state 更新时被 destroy → recreate

建议首先给下面这些位置加日志:

WKWebView init
makeUIView
updateUIView
dismantleUIView
load(url)
didStartProvisionalNavigation
didCommit
didFinish
didFail
didFailProvisionalNavigation
webViewWebContentProcessDidTerminate
deinit

如果页面每闪一下就能看到新的 makeUIView / WKWebView init,基本就能确认是 SwiftUI 生命周期问题。

如果 WKWebView 本身没重建,但不断触发:

webViewWebContentProcessDidTerminate

则继续排查 WebContent 进程崩溃。


P1:修复手势状态机

不要分别堆多个独立 gesture,而应该统一成明确状态:

enum InteractionState {
    case idle
    case webInteraction
    case twoFingerPending
    case voiceActive
    case swipingLeft
    case swipingRight
    case pencilDrawing
}

双指输入先进入:

twoFingerPending

之后根据:

  • 持续时间
  • 水平位移
  • 垂直位移
  • pinch scale
  • scroll velocity

再决定进入哪个最终状态。


P1:修复语音组件 anchor

进入 voiceActive 时只记录一次坐标:

voiceAnchorPoint = currentCenter

之后:

overlay.position = voiceAnchorPoint

不要继续:

overlay.position = currentTouchCenter

P1:恢复 Pencil 批注

等 WebView 生命周期稳定后,再确认:

WKWebView
+
Pencil overlay

是否保持长期一一对应,而不是页面更新就重新创建。


P2:单独验证 Speech Recognition

暂时绕过双指手势,加一个普通按钮:

Start Voice Test

点击后直接启动语音识别。

如果按钮版本也不能识别,则问题属于:

AVAudioSession / Speech / 权限

如果按钮版本可以识别,而双指版本不行,则问题基本就在:

gesture state machine / lifecycle

当前判断

日志里真正值得优先处理的并不是大量系统 Keyboard/UAF warning,而是:

页面持续闪烁
+
WebContent PID 不断变化
+
WebContent process termination / RBS assertion 日志持续出现

这很可能是当前所有交互异常的上游问题。

建议修复顺序:

WKWebView 生命周期 / WebContent 重启
        ↓
页面稳定
        ↓
Pencil overlay
        ↓
双指手势状态机
        ↓
语音组件固定位置
        ↓
左右滑操作
        ↓
Speech Recognition

不要先逐条消灭控制台里的系统 warning;先定位为什么一个页面运行期间会连续出现大量新的 WebContent[PID]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions