edit | blame | history | raw

2026-06-23 AppStore 四审会诊

用户目标

  • 查看 macOS App Version 2.1.28 再次被 Apple 拒绝的原因。
  • 拉上 4 位代码审核员会诊,确认到底是什么问题。
  • 本轮只做诊断和建议,不改代码、不打包、不上传、不在 App Store Connect 做提交动作。

Apple 拒审原文要点

  • Review date: June 23, 2026
  • Review Device: MacBook Air (15-inch, M2, 2023)
  • Version reviewed: 2.1.28 (20260614.102)
  • Guideline 2.4.5 - Performance
  • App requests access to Accessibility features but does not use them for accessibility purposes.
  • Specifically requests access to keystrokes for a non-accessibility purpose.
  • Apple 建议使用 NSEvent.addLocalMonitor 监听本 App 内的 mouse/key events。
  • Guideline 2.1(a) - Performance - App Completeness
  • Bug description: The app remains on a blank screen after launch.
  • Review device: MacBook Air M2 2023, macOS 26.5, Internet active.

四位审核员共识

  • 这次不是 quarantine、签名证书、entitlements 或 universal 架构问题。
  • 2.4.5 的主因是 MAS build 仍包含全局 keystroke 监听和 Accessibility 请求路径。
  • 2.1(a) 的主因方向是首屏 WebView/前端渲染没有被 QA 覆盖;现有 QA 只证明进程和 Wails 日志启动,不证明用户看到非空白界面。

关键证据

  • privatevoice.src/internal/hotkey/hotkey_darwin.go
  • 使用 CGEventTapCreate(kCGHIDEventTap, ..., kCGEventTapOptionListenOnly, ...) 监听 keyDown/keyUp/flagsChanged。
  • newPlatformListener() 启动时调用 AXIsProcessTrustedWithOptions,会触发 Accessibility 信任路径。
  • privatevoice.src/internal/input/paste_darwin.go
  • 自动上屏通过 CGEventPost 模拟 Cmd+V 或逐字键盘输入。
  • 失败时把 Accessibility 缺失作为错误返回。
  • privatevoice.src/internal/permissions/permissions_darwin.go
  • Accessibility 和 Input Monitoring 都被标记为 required。
  • privatevoice.src/frontend/src/App.svelte
  • languageReady 初始为 false。
  • 首屏必须等待 ConfigService.GetLanguageSettings 返回后才渲染 OnboardingViewSettingsWindow
  • 如果 Wails bridge、后端语言检测、沙盒子进程或 JS 初始化任一环节卡住,窗口可能无限空白。
  • Release/AppStore-2.1.28-20260614.0102-launchfix/RELEASE_MANIFEST.md
  • 启动证据只有 Application initialized, starting WailsWails application started
  • 构建命令使用了 PRIVATEVOICE_SKIP_FRONTEND_BUILD=1,增加前端 dist 与当前源码不一致的风险。
  • qa-macappstore-pkg-launch-macos.sh
  • 通过本地重签名 mirror 启动,不是最终 MAS-signed app 的真实安装/审核路径。
  • 只等待日志和进程存活,没有截图、像素非空白、窗口内容或 WebView console 断言。

结论

  1. 20260614.0102 不能再重新提交。
  2. 下一轮必须新 build。
  3. 仅回复 Apple 解释不足以解决问题;至少 MAS build 要移除或降级 Accessibility/keystroke 用途。
  4. App Store build 应考虑:
  • 移除启动期 Accessibility prompt。
  • 移除或禁用全局 CGEventTap 热键监听,改成本 App 内快捷键、按钮、菜单项,或只在非 MAS 版本保留全局热键。
  • 移除任意 App 自动键盘输入/自动粘贴,改为复制到剪贴板后提示用户手动粘贴,或重做为真正输入法/InputMethodKit 架构。
  1. 首屏必须先渲染可见 shell/loading/error,不能被第一条 Wails RPC 硬门控;所有首屏 RPC 应有超时和 fallback。
  2. QA 必须加入真实 UI 证据:最终安装路径、干净 TCC、无模型、首次启动、截图/录屏非空白、关键文本可见、可点击下载模型。

下一步建议

  • 先做 MAS 版本产品策略决策:App Store 版是否接受“无全局热键、无自动上屏,只复制到剪贴板/手动粘贴”的降级能力。
  • 如果不接受降级,则需要评估真正输入法架构或继续走非 App Store 分发。
  • 开发完成后,不得再只用日志 smoke;必须用真实 UI smoke 和 Apple 权限政策门禁作为上传前阻断项。