Route B · MVP Plan
路线 B 计划:iPhone 实时转写 + Watch best-effort 触发(Focus/Shortcuts/Siri)
2026-02-01 · 个人使用 · iPhone-only realtime · Watch best-effort
保留“实时转写”,把 Watch 触发收敛为 best-effort(不承诺锁屏口袋 100% 唤起录音)
目标是尽快把“稳定可用”的 iPhone 实时转写做成每天能用的工具:中文识别(on-device 优先,失败再网络兜底),音频备份 10 天后自动删除,文本永久保留;入口以 iPhone 快捷键/锁屏触发为主,Apple Watch 只负责触发一个可见的状态切换(Focus),再由 iPhone 自动化尽力唤起 App。
MVPzh-CNOn-device → Network fallbackAudio retention: 10 daysTranscript: foreverBest-effort Watch trigger
What you get
实时转写
iPhone OK
手表一键
Best-effort
音频留存
10 天后删
文本留存
永久
交付物(MVP)
- iPhone 端:
开始/停止→录音落盘→实时转写(partial + final)。 - 触发入口:App 内按钮 +
voicetranscribe://start|stop|toggle(Shortcuts/Siri 可调用)。 - Watch 触发:只做“可达时更方便”的 best-effort(Focus/Shortcuts/Siri),不写 100% 口袋唤起承诺。
- 留存策略:音频 10 天清理(尽力定期跑 + 每次 stop/启动时必跑一次);文本永久。
- 可验证的测试:Core 留存清理单测 + 设备手动测试清单(含失败路径)。
Best-minds 结论(把不确定性写进产品合同)
- Shortcuts/Focus 专家视角:把 Watch 当“遥控开关”,Focus 是最稳的跨设备信号;但“后台无感开麦”不可依赖。
- iOS 音频/语音工程视角:实时转写要先把音频会话、后台 Audio、权限弹窗做对;触发入口越少越稳。
- 平台安全视角:麦克风属于高敏感权限,系统会主动阻止从后台/自动化悄悄录音;承诺 100% 很容易变成“产品债”。
Hard boundaries
明确不做(至少在 MVP)
- 不做 watchOS App / Complication(只用 Watch 端 Shortcuts/Focus/Siri)。
- 不承诺“锁屏 + 口袋 + 一键必开录”(只承诺 best-effort + 明确失败提示/替代路径)。
- 不做云端同步/上传(后续再考虑 GitHub / Cloudflare R2 / Vercel)。
- 不做说话人分离、长音频二次转写、复杂降噪。
必须面对的系统限制
- Shortcuts/自动化对“打开 App/录音”这类敏感动作存在提示/限制,且不同 iOS 版本差异很大。
- Watch 触发 iPhone 的即时性不稳定:取决于可达性、系统状态、是否需要解锁。
- Speech on-device 能力与机型/系统/语言包有关;必须准备网络兜底路径。
体验路径(把“失败”也设计出来)
主路径:iPhone 一键(推荐)
- 用户通过 Action Button / 锁屏小组件 / Back Tap 触发快捷指令。
- 快捷指令:
打开 URL→voicetranscribe://toggle。 - App 前台/可唤起时:立即开始录音 + 实时转写;屏幕可锁,录音继续。
- 录制结束:写入
meta.json/transcript.json,并触发一次“清理旧音频”。
辅助路径:Watch 一键(Best-effort)
- Watch Complication 运行快捷指令:切换 Focus
Recording。 - iPhone 自动化(Focus 开启/关闭)尽力执行:
- 理想:打开 URL(start/stop)。
- 保底:显示通知/震动提示“点开开始/结束”。
- 如果 iPhone 需要解锁/无法后台开麦:用户看到明确提示,不会误以为“已经在录”。
产品合同(非常关键):“Watch 触发 ≠ 录音必定开始”。我们把它定义成 best-effort,并在失败时给出清晰反馈与下一步(打开 App 即可开始)。
系统结构(单端实时 + 双端触发)
实施路线(按可验证里程碑)
| Milestone | 做什么 | 怎么验收(你能亲手验证) |
|---|---|---|
| M0 · 触发链路跑通 |
|
你在 Watch 点一下,iPhone 锁屏也能稳定出现“通知/计时器变化/Focus 状态变化”。 |
| M1 · iPhone 实时转写 MVP |
|
App 前台点击开始/停止:能看到实时文字滚动;录音结束后能在本地目录看到 3 个文件。 |
| M2 · Shortcuts/Siri 接入 |
|
锁屏点一下快捷指令:App 被唤起并开始录音(或明确提示需要解锁/打开 App)。 |
| M3 · 留存清理与“失败可见” |
|
制造一个 11 天前的音频文件,触发清理后音频被删但 transcript 仍在;Watch 触发失败时能看到提示。 |
Best-effort 触发:可靠性矩阵(写进预期)
测试策略(先把可测的做成可测)
自动化测试(现在就能跑)
- Core:留存清理单测(删音频不删文本/元数据)。
- Core:文件结构与 JSON 编解码(可加更多边界测试)。
当前已跑通的命令
CLANG_MODULE_CACHE_PATH=/tmp/clang-module-cache swift test --disable-sandbox --package-path apps/voiceTranscribeMVP/VoiceTranscribeCore
设备手动测试(必须做)
- 权限:首次授权麦克风/语音识别后的行为。
- 识别:on-device 可用/不可用 → 网络兜底是否正常。
- 触发:
- iPhone(Action Button/锁屏小组件/Back Tap)
- Watch(切 Focus → iPhone 自动化)
- 失败路径:无法开录时必须给出“你现在没在录”的信号。
风险与对策(提前写掉未来的坑)
风险:触发不稳定 → 用户误判
- 对策:任何 start/toggle 都要落一个“可见状态”(通知/状态条/音效/震动)。
- 对策:失败时明确提示“需要解锁/打开 App 才能开始”。
风险:功耗/发热/存储
- 对策:默认 PCM
.caf先跑通;后续切 AAC.m4a降体积。 - 对策:音频 10 天清理必跑;给一个手动“立即清理”入口。
风险:on-device 不可用
- 对策:先尝试 on-device;失败自动切网络兜底,并把原因写入 meta(便于你排查)。
风险:分发与安装
- 对策:MVP 先按“你自己能装到手机上”的方式推进(后续再决定是否上架/付费账号)。
Closing summary
一句话总结
路线 B 的核心是:把价值压在 iPhone 端“确定性实时转写” 上;把 Watch 触发定义为 best-effort,并把失败设计成“可见、可纠正”。
One next action
先按 docs/shortcuts_runbook.md 跑通 “Watch 切 Focus → iPhone 自动化无提示执行” 的链路(用通知/计时器验证),跑通后再把自动化动作替换成“打开 URL”。
先把“能稳定工作”的部分做到极致,再把“不稳定的触发”标成 best-effort。
Route B · Product Contract