c398a8dd58d42736fce6c293591c9df2b1e9e706
完整支撑 Phase 3.E prepareaudio handler 的录音子链路:用户按住 H5 麦克风按钮 → Native 录音 → 松手停止 → 触发完成回调。 ## 新增模块 - `RecordingAwareWindow`:UIWindow 子类,提供 touch 旁路监听通道 (static touchObserver closure)。默认行为与 UIWindow 完全一致,仅 RecordingPresenter 注册 observer 后才触发额外行为。daoqi msext CustomWindow.m + nScreenTouch 通知同款思路,改用 closure 注入 - `VoiceRecorder`:AVAudioRecorder + AudioSession + 0.1s 计时器封装。 ObservableObject + @Published(暴露 averagePower / elapsed 给 SwiftUI)。 录音参数 8kHz/16bit/mono PCM 严格对齐 daoqi(AMR-NB 编码硬要求)。 60s 上限对齐 daoqi kDefaultMaxRecordTime - `RecordingOverlay`:SwiftUI 浮层(UI 内部实现,按 CLAUDE.md「原则 B 原生 内部自由」与 daoqi 不一致)。半透明黑底胶囊 + SF Symbols 麦克风 + 音量 光晕动画 + 倒计时(剩 10s 显示秒数,对齐 daoqi UI 逻辑) - `RecordingPresenter`:组装入口。挂载 overlay 到 hostVC 全屏覆盖 + 注册 touchObserver。提供 `start(on:fileName:onFinish:)` 单一 API + `cancelActive()` 强制取消 ## SceneDelegate 改动 UIWindow → RecordingAwareWindow 实例化。变量类型仍为 UIWindow? (多态),sendEvent 走子类版本。零行为变化(observer 未注册时)。 ## 为何必须走 UIWindow 子类 H5 麦克风按钮按下触发 prepareaudio → 录音浮层在按住状态下中途弹出。 iOS touch 事件流是 view hit-test 链,**in-flight touch 不传给中途加入 的 view**,浮层 view 自身收不到 touchesEnded,用户松手时检测不到。 唯一可靠路径是 UIWindow.sendEvent 旁路截获(UIWindow 接收所有 touch event 无论 in-flight 还是新 touch)。daoqi msext 也是这条路。 ## Combine 引入 VoiceRecorder 用 ObservableObject + @Published 给 SwiftUI 数据绑定, 需要 import Combine。CLAUDE.md「避免 Combine」精神是禁用 Publisher 链 替代 async/await,不是禁止 ObservableObject(iOS 15.6 无 @Observable 宏可替代)。已在 VoiceRecorder.swift 注释说明。 ## 验证 BuildProject 通过 0 错误,全部新文件 XcodeRefreshCodeIssuesInFile 0 诊断。
Description
No description provided
24 MiB
Languages
Swift
94.5%
Objective-C++
2.9%
JavaScript
1.8%
C
0.6%
Objective-C
0.2%