// 容器 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)") } } } }