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

时间:2015-12-14 13:16:56

标签: ios swift avaudiosession avaudioengine

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

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

self.engine被定义为

private let engine = AVAudioEngine()

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

  

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

在包含try self.engine.start()

的行上

561015905是AVAudioSessionErrorCodeCannotStartPlaying根据我的理解,这应该是NSError错误代码,而不是例外情况,我应该在上面的代码中抓住空白catch。不过,该应用程序似乎只是崩溃了。我错过了什么?

我知道存在该应用程序在后台醒来时可能发生这个错误,我会被罚款这一说法,只要我能以某种方式赶上它的发生,因为我以为我可以的情况下do/catch

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

Xcode版本9.2(9C40b)+ Swift 4:我知道这个问题有点旧,但是,即使在do / try / catch中,我也遇到了与audioEngine.start()相同的崩溃问题来自Crashalytics:

  

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

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

最后,我使用Obj-C异常处理来真正捕获错误,所以没有崩溃,从freytag这个非常有用的帖子(非常感谢!):

Catching NSException in Swift

现在,在实现了ObjC .h和.m文件以及桥接头之后,我做了:

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

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

  

2018-01-06 10:01:48.890801 + 0700 XXXXXX [16389:3367770] [avae] AVAEInternal.h:70:_AVAE_Check:必需条件为false:[AVAudioEngineGraph.mm:1209:Initialize :( inputNode!= nullptr || outputNode!= nullptr)]   发生错误:错误域= com.apple.coreaudio.avfaudio代码= 0“(null)”

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

func play(soundName: String) {
    if !audioEngine.isRunning {
        return
    }
    // play sound
 }

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

看起来很荒谬,在Swift中你无法正常捕获异常,如果你要做一些不能捕获的异常,那么至少提供一种先测试的方法,比如audioEngine.areYouConfiguredProperly()。哦,挂起就是这个方法(在Obj-C中)[AVAudioEngine startAndReturnError:]但有人决定用startEngine()函数包装它并取消所有有用的功能...... doh。