AudioPlayerDidFinishPlaying 永远不会被调用,所以 "other sounds" 保持 "ducked" - 我做错了什么?

AVAudioPlayerDidFinishPlaying never gets called, so "other sounds" remain "ducked" - What am I doing wrong?

关于这个主题的问题很多,但大多数都太老了,答案不再适用,因为 Swift 和 iOS 自发布以来已经发生了很大变化。乍一看看起来很有帮助的几个实际上并没有告诉我任何我还没有弄清楚的事情,也没有做任何事情来帮助我解决问题的化身,尽管看起来与我的问题几乎相同我有。

除了 AVAudioPlayerDidFinishPlaying 永远不会被调用(因此离开 "other sounds" 由设备 "ducked" 直到应用程序完全关闭)下面的代码在模拟器和物理 iPhone 7 加上 运行 iOS 13.3。如果它有所作为,我将编码为 Swift 5.1,目标 iOS 13.3,在 Xcode 11.3 中,在运行 Catalina (10.15.2) 的平台上。

这是 "broken" 代码:

import Foundation
import AVFoundation

class NoiseMaker: NSObject, AVAudioPlayerDelegate {
    var ourSession = AVAudioSession()
    var ourPlayer  = AVAudioPlayer()

    func playSound(sound: String) {
        print("Entered NoiseMaker.playSound(sound: \(sound))")
        let theURL: URL = Bundle.main.url(forResource: sound, withExtension: "mp3")!

        try!ourSession.setCategory(AVAudioSession.Category.ambient, options: AVAudioSession.CategoryOptions.duckOthers)
        try!ourSession.setActive(true)
        ourPlayer.delegate = self
        ourPlayer.prepareToPlay()
        do {
            ourPlayer = try AVAudioPlayer(contentsOf: theURL)
            ourPlayer.play()
        } catch let theError as NSError {
            print("Couldn't load \(sound).mp3 - Error \(theError)")
        }
    }

    // MARK: - AVAudioPlayer delegate methods
    // Never gets called - Other sound sources remain "ducked" until the app is completely shut down.
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("Arrived in audioPlayerDidFinishPlaying")
        try!ourSession.setActive(false)
    }

    func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {
        print("Decoding error from AVAudioPlayer: \(error!.localizedDescription)")
    }
}

如前所述,一切都按预期工作 - 除了我的 audioPlayerDidFinishPlaying 方法从未被调用,这意味着我永远没有机会 "unduck" 其他可能正在播放的声音。 (尽管应用程序完全关闭后一切 "unducks")

为什么?我怎么搞砸了这看似微不足道的任务?

我看到了问题,您将 self 设置为委托,但随后将引用更改为 AVAudioPlayer

的新实例

您应该在此处创建新实例后设置委托

ourPlayer = try AVAudioPlayer(contentsOf: theURL)
ourPlayer.delegate = self
ourPlayer.play()