3.E 修复:换用 iOS 17+ AVAudioApplication.requestRecordPermission 避免 EXC_BREAKPOINT

## 问题

第一次调用 prepareaudio 弹出系统权限对话框,用户点允许/拒绝都触发
Thread 10 EXC_BREAKPOINT 崩溃。

## 根因猜测

deprecated 的 AVAudioSession.requestRecordPermission(_:) 在
iOS 26.5 SDK 上内部桥接到 AVAudioApplication 时,与
withCheckedContinuation 的 Swift Concurrency 状态机交互异常。
具体表现:completion 在 Thread 10 触发 cont.resume(returning:),
runtime 检测到某种 actor / continuation 状态违规,触发 trap。

## 修复

新增 `requestMicrophonePermission()` 私有助手:

```swift
if #available(iOS 17.0, *) {
    return await AVAudioApplication.requestRecordPermission()  // 原生 async
} else {
    return await withCheckedContinuation { ... }              // 旧 SDK 兼容
}
```

iOS 17+ 走原生 async API,不经 Continuation 状态机,避开 corner case;
iOS 15.6 / 16 走 deprecated API 兼容路径。

## 验证

BuildProject 通过 0 错误。真机首次启动 → 按录音按钮 → 系统权限对话框
出现 → 点允许/拒绝 → 应无崩溃。
This commit is contained in:
joywayer
2026-06-24 02:05:25 +08:00
parent 6f10d231ad
commit 7d89a9d3ee
@@ -101,11 +101,13 @@ public enum RemoteAudioHandler {
// **** touchObserver // **** touchObserver
// touchObserver "" stop // touchObserver "" stop
// / .authorized // / .authorized
_ = await withCheckedContinuation { cont in //
AVAudioSession.sharedInstance().requestRecordPermission { granted in // iOS 17+ AVAudioApplication.requestRecordPermission()
cont.resume(returning: granted) // asyncSwift Concurrency iOS 26+
} // deprecated AVAudioSession.requestRecordPermission(_:) +
} // withCheckedContinuation Thread 10
// EXC_BREAKPOINT API
_ = await requestMicrophonePermission()
// cb daoqi ifauth==1 daoqi NewRootVC.m:322 // cb daoqi ifauth==1 daoqi NewRootVC.m:322
// [recorderVC beginRecordByFileName:] responseCallback // [recorderVC beginRecordByFileName:] responseCallback
// //
@@ -336,6 +338,29 @@ public enum RemoteAudioHandler {
callback?(.string("Response from mediaTypeAudio")) callback?(.string("Response from mediaTypeAudio"))
} }
///
///
/// iOS 17+ `AVAudioApplication.requestRecordPermission()` async
/// iOS 15.6 / 16 deprecated `AVAudioSession.requestRecordPermission(_:)` +
/// withCheckedContinuation
///
/// **** deprecated API SDK iOS 26.5 SDK deprecated
/// API AVAudioApplication withCheckedContinuation
/// Thread 10 EXC_BREAKPOINT bug Swift Concurrency
/// ObjC corner case API await Continuation
///
private static func requestMicrophonePermission() async -> Bool {
if #available(iOS 17.0, *) {
return await AVAudioApplication.requestRecordPermission()
} else {
return await withCheckedContinuation { (cont: CheckedContinuation<Bool, Never>) in
AVAudioSession.sharedInstance().requestRecordPermission { granted in
cont.resume(returning: granted)
}
}
}
}
@MainActor @MainActor
private static func showMicrophonePermissionAlert(on hostVC: UIViewController?) { private static func showMicrophonePermissionAlert(on hostVC: UIViewController?) {
// iOS // iOS