Skip to content

feat(ios): OpenLess iOS 语音输入法(初版工程 + 火山流式 ASR + Flow 语音面板) - #624

Merged
H-Chris233 merged 1 commit into
mainfrom
feat/ios-voice-input
Jun 9, 2026
Merged

H-Chris233 merged 1 commit into
mainfrom
feat/ios-voice-input

Conversation

@appergb

@appergb appergb commented Jun 9, 2026 •

Copy link
Copy Markdown
Collaborator

User description

概述

新增 1-app/openless-ios/:OpenLess 的 iOS 端语音输入法(独立 XcodeGen 工程,与桌面端 openless-all/ 平级、互不混入)。以语音输入为核心,复刻桌面云端 ASR,键盘做成 Flow 式语音面板。

工程结构(3 target)

  • OpenLess(主 App / SwiftUI):录音 → ASR → 润色 → 配置/凭据
  • OpenLessKeyboard(键盘扩展):Flow 式语音面板(非打字键盘)
  • OpenLessShared(共享框架):数据模型 / 存储 / ASR 协议
  • App Group group.top.openless.ios;XcodeGen project.yml 为唯一真源(.xcodeproj 不入库)

已实现

  • 数据模型对齐桌面 types.rs/persistence.rs(StylePack / Preferences / Credentials),JSON camelCase
  • 设置页:润色模式 + ASR/LLM provider 选择 + Key 录入(沙盒 JSON 持久化,含「保存」反馈)
  • 云端 ASR:移植桌面火山 SAUC bigmodel 流式 ASR(URLSessionWebSocket + 二进制分帧 VolcFrame + 48k→16k Int16 重采样);按配置选引擎(火山有 Key 走火山,否则退回 Apple Speech),界面显示当前引擎
  • 键盘:语音面板(透出系统毛玻璃、麦克风键、设置/删除/切键盘),跳主 App 录音 → App Group 回插;未开完全访问时键盘内提示
  • PiP 免跳转骨架:PiPVoiceController(AVSampleBufferDisplayLayer 自定义画中画保活)+ VoiceBridge(Darwin 通知 + App Group 进程间桥)

关键平台约束(务必知悉)

  • iOS 键盘扩展无法访问麦克风(Apple 沙盒,已查证)→ 录音必须在主 App,键盘经 App Group 回插
  • PiP 仅真机可用(模拟器 isPictureInPictureSupported()==false)→ 免跳转语音只能真机验证
  • 免费个人开发者账号不支持 App Group → 真机完整键盘回插需付费账号;待评估用 Keychain Sharing 替代

状态 / TODO

  • 工程骨架 + 设置 + 火山流式 ASR + Flow 语音面板(模拟器构建通过)
  • PiP 免跳转完整链路(键盘触发后台录音 → 回插,真机)
  • 风格包市场拉取/安装;LLM 润色接入;词汇表/纠错规则
  • 免费账号回插方案(Keychain Sharing)

测试

  • 模拟器:cd 1-app/openless-ios && ./scripts/run-sim.sh(adhoc 签名让 App Group 生效)
  • App 内 🎤 语音输入:配好火山 Key 后实时转写
  • 真机 / PiP:各自 Apple ID 签名(真机);PiP 仅真机

🤖 Generated with Claude Code


PR Type

Enhancement


Description

  • New iOS voice input method project

  • Volcengine streaming ASR integration

  • Flow-style keyboard extension

  • Background PiP and inter-process bridge

  • Settings UI for providers and credentials


Diagram Walkthrough

flowchart LR
    K["Keyboard Extension"] -- "openless://dictate" --> A["Main App"]
    A -- "AVAudioEngine" --> V["Volcengine ASR"]
    V -- "PCM Audio" --> WS["WebSocket"]
    WS -- "Text" --> AG["App Group"]
    A -- "PiP Stay Alive" --> P["Picture in Picture"]
    K -- "Fetch Text" --> AG
    K -- "Insert" --> TI["Text Field"]
Loading

File Walkthrough

Relevant files
Configuration changes
6 files
run-sim.sh
Simulator build script with adhoc signing                               
+36/-0   
Info.plist
Main app plist with permissions and URL scheme                     
+65/-0   
OpenLess.entitlements
App Group entitlement for main app                                             
+11/-0   
Info.plist
Keyboard extension plist with full access                               
+44/-0   
OpenLessKeyboard.entitlements
Keyboard App Group entitlement                                                     
+11/-0   
project.yml
XcodeGen project definition with 3 targets                             
+76/-0   
Enhancement
12 files
VolcengineASR.swift
Volcengine streaming ASR client                                                   
+164/-0 
DictationView.swift
Flow voice dictation UI                                                                   
+146/-0 
OpenLessApp.swift
App entry point with shared store init                                     
+20/-0   
PiPVoiceController.swift
Background PiP controller for audio                                           
+148/-0 
RootView.swift
Root view with dictation sheet                                                     
+25/-0   
SettingsModel.swift
Settings model with auto-save                                                       
+57/-0   
SettingsView.swift
Settings UI for preferences and credentials                           
+159/-0 
SpeechDictator.swift
Speech dictator managing ASR engines                                         
+225/-0 
KeyboardViewController.swift
Keyboard extension with mic button and text insert             
+183/-0 
VolcFrame.swift
Binary frame encoding for Volcengine ASR                                 
+108/-0 
SharedStore.swift
Shared JSON store in App Group                                                     
+66/-0   
VoiceBridge.swift
Inter-process bridge via Darwin notifications                       
+60/-0   
Documentation
1 files
README.md
Project documentation and build instructions                         
+52/-0   
Additional files
11 files
Contents.json +20/-0   
Contents.json +14/-0   
Contents.json +6/-0     
Info.plist +22/-0   
Credentials.swift +64/-0   
PolishMode.swift +19/-0   
Preferences.swift +73/-0   
StylePack.swift +105/-0 
AppGroup.swift +20/-0   
Handoff.swift +19/-0   
KeychainStore.swift +62/-0   

新增 1-app/openless-ios/:独立 XcodeGen 工程(3 target:主App/键盘扩展/共享框架),与桌面端 openless-all/ 平级、互不混入。

- 数据模型对齐桌面 types.rs/persistence.rs(StylePack/Preferences/Credentials),camelCase JSON
- 设置页:润色模式 + ASR/LLM provider 与 Key 录入(沙盒 JSON 持久化)
- 云端 ASR:移植桌面火山 SAUC bigmodel 流式 ASR(WebSocket + 二进制分帧 + 16k 重采样),按配置选引擎(火山有 Key 走火山,否则退回 Apple Speech)
- 键盘:Flow 式语音面板(非打字键盘),跳主App录音 + App Group 回插
- PiP 免跳转保活骨架(AVSampleBufferDisplayLayer 自定义画中画)+ VoiceBridge 进程间桥

已知约束:iOS 键盘扩展不能录音(语音走主App);PiP 仅真机;免费开发者账号不支持 App Group。
@H-Chris233
H-Chris233 merged commit e776ba1 into main Jun 9, 2026
4 checks passed
@appergb
appergb deleted the feat/ios-voice-input branch September 9, 2026 05:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants