40760aa884
- server:Go 网关(WS 流式识别中继/计费配额/微信登录支付 mock/反馈/埋点),gummy provider 已真实联调 - desktop:Tauri 2(全局快捷键 push-to-talk/浮层/托盘/设置/登录购买/反馈/首启引导) - android:Compose 主 App + IME(键盘内录音直传) - ios:App + 键盘扩展(1A spike 实证键盘内不可录音,走 deep link 听写) - design/design-pipeline:设计系统 + token 导出 iOS/Android 主题 - doc:前后端设计文档(HTML);web:官网宣传页;todo:任务看板 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
61 lines
2.1 KiB
Swift
61 lines
2.1 KiB
Swift
// 容器 App:引导启用键盘 + 在 App 内先验证一次正常录音(对照组)
|
||
import AVFoundation
|
||
import SwiftUI
|
||
|
||
@main
|
||
struct SpikeApp: App {
|
||
var body: some Scene {
|
||
WindowGroup { ContentView() }
|
||
}
|
||
}
|
||
|
||
struct ContentView: View {
|
||
@State private var appMicResult = "未测试"
|
||
|
||
var body: some View {
|
||
VStack(alignment: .leading, spacing: 16) {
|
||
Text("dudu 键盘录音 spike").font(.title2).bold()
|
||
Text("""
|
||
步骤:
|
||
1. 点下方按钮,先验证 App 内录音(对照组)
|
||
2. 设置 → 通用 → 键盘 → 添加 DuduKbMicSpike
|
||
3. 打开"允许完全访问"
|
||
4. 任意输入框切到该键盘,按"测试键盘内录音"
|
||
5. 把键盘上显示的结果告诉 Claude
|
||
""").font(.callout)
|
||
Button("测试 App 内录音(对照组)") {
|
||
testAppMic { appMicResult = $0 }
|
||
}
|
||
.buttonStyle(.borderedProminent)
|
||
Text("App 内结果:\(appMicResult)").font(.callout).monospaced()
|
||
Spacer()
|
||
}
|
||
.padding(24)
|
||
}
|
||
}
|
||
|
||
func testAppMic(done: @escaping (String) -> Void) {
|
||
AVAudioApplication.requestRecordPermission { granted in
|
||
DispatchQueue.main.async {
|
||
guard granted else { return done("麦克风权限被拒") }
|
||
do {
|
||
let session = AVAudioSession.sharedInstance()
|
||
try session.setCategory(.record, mode: .measurement)
|
||
try session.setActive(true)
|
||
let engine = AVAudioEngine()
|
||
var frames: UInt32 = 0
|
||
engine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: nil) { buf, _ in
|
||
frames += buf.frameLength
|
||
}
|
||
try engine.start()
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||
engine.stop()
|
||
done(frames > 0 ? "✅ 收到 \(frames) 帧" : "❌ 无音频回调")
|
||
}
|
||
} catch {
|
||
done("❌ \(error.localizedDescription)")
|
||
}
|
||
}
|
||
}
|
||
}
|