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:
@@ -101,11 +101,13 @@ public enum RemoteAudioHandler {
|
||||
// 首次启动:弹系统权限对话框,**不**启动录音浮层(避免与 touchObserver
|
||||
// 死锁——touchObserver 会捕获用户松手点"允许"的动作立刻 stop 录音)。
|
||||
// 用户做完选择 / 第二次按录音按钮时走 .authorized 分支正常录音。
|
||||
_ = await withCheckedContinuation { cont in
|
||||
AVAudioSession.sharedInstance().requestRecordPermission { granted in
|
||||
cont.resume(returning: granted)
|
||||
}
|
||||
}
|
||||
//
|
||||
// 优先用 iOS 17+ 的 AVAudioApplication.requestRecordPermission()
|
||||
// (原生 async,Swift Concurrency 一等公民);iOS 26+ 上
|
||||
// deprecated 的 AVAudioSession.requestRecordPermission(_:) +
|
||||
// withCheckedContinuation 桥接路径实测会触发 Thread 10
|
||||
// EXC_BREAKPOINT(疑似系统内部桥接新 API 时状态机异常)。
|
||||
_ = await requestMicrophonePermission()
|
||||
// ⚠️ 必须触发 cb(对齐 daoqi ifauth==1 路径行为,daoqi NewRootVC.m:322
|
||||
// 在 [recorderVC beginRecordByFileName:] 后总是 responseCallback)。
|
||||
//
|
||||
@@ -336,6 +338,29 @@ public enum RemoteAudioHandler {
|
||||
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
|
||||
private static func showMicrophonePermissionAlert(on hostVC: UIViewController?) {
|
||||
// 用户已拒绝麦克风权限时调用。iOS 不允许再次主动弹系统权限对话框
|
||||
|
||||
Reference in New Issue
Block a user