AVAudioEngine.start()崩溃,即使它包含在do/catch中

Mik*_*ike 12 ios avaudiosession swift avaudioengine

我有以下代码(重新)开始AVAudioEngine连接到AVAudioEngineConfigurationChangeNotification:

   do {
       try self.engine.start()
   } catch {
       DDLogError("could not start sound engine")
       self.soundEnabled = false
       return
   }
Run Code Online (Sandbox Code Playgroud)

self.engine定义为

private let engine = AVAudioEngine()
Run Code Online (Sandbox Code Playgroud)

但是,我经常通过Crashlytics收到崩溃报告

致命异常:com.apple.coreaudio.avfaudio错误561015905

在包含的线上try self.engine.start().

561015905是AVAudioSessionErrorCodeCannotStartPlaying从我的理解,这应该是一个NSError错误代码,而不是一个例外,应该由我catch在上面的代码中的空白捕获.不过,该应用程序似乎只是崩溃了.我错过了什么?

我知道有些情况下应用程序会在可能发生此错误的后台唤醒,我会很好,只要我能够以某种方式发现它,就像我想的那样do/catch.

S1L*_*IOR 5

我在处理通知时遇到了同样的错误AVAudioSessionInterruption。就我而言,当我在中断结束后
尝试启动时,出现了错误。 经过一段时间的详细测试和调试后,我注意到如果我引入before或. 所以我之前添加了,我的应用程序停止崩溃了! AVAudioEngine
debugger breakpointaudioEngine.prepare()audioEngine.start()
sleep(1)audioEngine.start()

我知道这不是一个非常优雅的解决方案,但仍然希望这可以帮助其他人!


Chr*_*rri 5

Xcode 版本 9.2 (9C40b) + Swift 4 :我知道这个问题有点老了,但是,audioEngine.start()即使在 do/try/catch 中我也遇到了同样的崩溃问题,并且还从 Crashalytics 收到以下信息:

致命异常:com.apple.coreaudio.avfaudio 错误 561015905

S1LENT WARRIOR 的 sleep(1) "hack" 在某些情况下有效,但不是全部(特别是 AVAudioEngineConfigurationChangeNotification 选择器)。

最后,我使用 Obj-C 异常处理来真正捕获错误,因此不会发生崩溃,来自 freytag 的这篇非常有用的帖子(非常感谢!):

在 Swift 中捕获 NSException

现在,在实现 ObjC .h 和 .m 文件以及桥接头之后,我执行以下操作:

do {
    try ObjC.catchException {
        try! self.audioEngine.start()
    }
}
catch {
    print("An error occurred: \(error)")
}
Run Code Online (Sandbox Code Playgroud)

您可以通过搞砸引擎初始化(例如,不要 .attach 或 .connect 任何东西)来测试这一点,并且不会崩溃……仅:

2018-01-06 10:01:48.890801+0700 XXXXXX[16389:3367770] [avae] AVAEInternal.h:70:_AVAE_Check: 所需条件为假:[AVAudioEngineGraph.mm:1209:Initialize: (input ||Node! outputNode != nullptr)] 发生错误:Error Domain=com.apple.coreaudio.avfaudio Code=0 "(null)"

确保在使用之前检查 audioEngine 正在运行,例如:

func play(soundName: String) {
    if !audioEngine.isRunning {
        return
    }
    // play sound
 }
Run Code Online (Sandbox Code Playgroud)

好的,所以你没有声音,但这是一个“优雅的失败”。

在 Swift 中您无法正确捕获异常似乎很荒谬,如果您要使某些异常无法捕获,那么至少提供一种首先进行测试的方法,例如audioEngine.areYouConfiguredProperly(). 哦,等等,有这个方法(在 Obj-C 中),[AVAudioEngine startAndReturnError:]但有人决定用startEngine()函数包装它并取消所有有用的功能......呵呵。