背景
项目: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. 双指按住组件会跟随手指移动
当前设计是:
双指静止按住一段时间后触发语音输入组件。
预期行为:
- 双指按住约 0.45 秒
- 达到阈值后,在触发位置显示语音组件
- 组件出现后应固定在触发时的位置
- 后续手指轻微移动不应该让组件跟随移动
- 用户松开或完成操作后再结束该状态
当前实际行为:
- 组件出现后仍会跟随双指移动
- 视觉上像组件被绑定到了实时 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:
这看起来主要属于系统键盘内部约束冲突,目前不是页面闪烁的第一嫌疑,但需要观察是否由频繁 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
目前看更像系统内部日志,优先级较低,不应作为主问题处理。
预期结果
真机上应该达到:
- 配对后 WebView 页面稳定显示,不再闪烁
- WebContent 进程不再不断生成/退出
- Apple Pencil 可以直接在网页上正常批注
- 批注位置绑定网页内容坐标
- 手指仍可以滚动和缩放网页
- 双指静止约 0.45 秒后进入语音模式
- 语音组件出现后固定在触发位置,不跟随手指移动
- 双指左滑触发左侧按钮
- 双指右滑触发右侧按钮
- swipe / scroll / pinch / voice 几种状态之间互斥
- 语音转文字可以在真机正常工作
建议排查优先级
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
}
双指输入先进入:
之后根据:
- 持续时间
- 水平位移
- 垂直位移
- pinch scale
- scroll velocity
再决定进入哪个最终状态。
P1:修复语音组件 anchor
进入 voiceActive 时只记录一次坐标:
voiceAnchorPoint = currentCenter
之后:
overlay.position = voiceAnchorPoint
不要继续:
overlay.position = currentTouchCenter
P1:恢复 Pencil 批注
等 WebView 生命周期稳定后,再确认:
WKWebView
+
Pencil overlay
是否保持长期一一对应,而不是页面更新就重新创建。
P2:单独验证 Speech Recognition
暂时绕过双指手势,加一个普通按钮:
点击后直接启动语音识别。
如果按钮版本也不能识别,则问题属于:
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]。
背景
项目:TouchCode
当前在真机测试中,设备已经可以正常完成配对,但进入实际交互后存在多个严重问题,主要集中在
WKWebView、Pencil 批注层、双指手势以及语音转文字功能。目前应用可以启动和配对,但核心交互基本不可用。
当前现象
1. 页面无法稳定显示,持续闪烁
配对完成后,页面不能正常稳定显示,
WKWebView / WebContent似乎在不断重建、崩溃或重新拉起。表现为:
WebContent进程不断出现Failed to terminate process/No such process found日志中大量重复出现:
还伴随:
这个问题目前优先级最高,因为页面持续闪烁会直接导致后续 Pencil、手势等功能无法正常工作。
2. Pencil 无法正常在页面上批注
当前 Apple Pencil 无法稳定地在网页上进行批注。
预期:
实际:
需要重点确认:
PKCanvasView/ 自定义 overlay 是否跟随 WebView 被重复创建3. 双指按住组件会跟随手指移动
当前设计是:
双指静止按住一段时间后触发语音输入组件。
预期行为:
当前实际行为:
.voiceActive状态时冻结 anchor point建议进入语音状态的一瞬间保存:
voiceAnchorPoint = currentTwoFingerCenter之后 UI 永远使用
voiceAnchorPoint,不要继续使用实时 touch center。4. 双指左右滑应触发两侧按钮操作
需要补充/修正双指手势状态机。
预期:
建议逻辑:
同时:
5. 语音转文字目前无法正常使用
当前语音输入流程无法正常完成语音转文字。
需要检查完整链路:
需要确认:
NSMicrophoneUsageDescriptionNSSpeechRecognitionUsageDescriptionAVAudioSession是否正确 activateSFSpeechRecognitionTask日志中的其他异常
Keyboard Auto Layout constraint 冲突
日志中出现:
其中关键冲突:
UIKit 最终主动 break:
这看起来主要属于系统键盘内部约束冲突,目前不是页面闪烁的第一嫌疑,但需要观察是否由频繁 first responder 切换触发。
System Gesture Gate 超时
这个和当前自定义双指手势存在较强相关性,需要重点排查:
.possibleReporter / Fence timeout
可能是 UI / rendering pipeline 在频繁重建或卡顿后的次生症状。
UAF / linguisticdata / boot UUID
目前看更像系统内部日志,优先级较低,不应作为主问题处理。
预期结果
真机上应该达到:
建议排查优先级
P0:先解决 WebView 持续闪烁 / WebContent 重启
这是当前最核心问题。
重点检查:
WKWebView是否被 SwiftUIbody/updateUIView不断重新创建WKWebViewConfiguration是否重复创建load(...).id(...)UIViewRepresentable的 Coordinator 生命周期webViewWebContentProcessDidTerminate中立即 reload,形成死循环建议首先给下面这些位置加日志:
如果页面每闪一下就能看到新的
makeUIView/WKWebView init,基本就能确认是 SwiftUI 生命周期问题。如果
WKWebView本身没重建,但不断触发:则继续排查 WebContent 进程崩溃。
P1:修复手势状态机
不要分别堆多个独立 gesture,而应该统一成明确状态:
双指输入先进入:
之后根据:
再决定进入哪个最终状态。
P1:修复语音组件 anchor
进入
voiceActive时只记录一次坐标:voiceAnchorPoint = currentCenter之后:
不要继续:
P1:恢复 Pencil 批注
等 WebView 生命周期稳定后,再确认:
是否保持长期一一对应,而不是页面更新就重新创建。
P2:单独验证 Speech Recognition
暂时绕过双指手势,加一个普通按钮:
点击后直接启动语音识别。
如果按钮版本也不能识别,则问题属于:
如果按钮版本可以识别,而双指版本不行,则问题基本就在:
当前判断
日志里真正值得优先处理的并不是大量系统 Keyboard/UAF warning,而是:
这很可能是当前所有交互异常的上游问题。
建议修复顺序:
不要先逐条消灭控制台里的系统 warning;先定位为什么一个页面运行期间会连续出现大量新的
WebContent[PID]。