Swift 3 AVFoundation 停止上一个 AVAudioPlayer

Swift 3 AVFoundation Stop previous AVAudioPlayer

我有一个名为 PlayerController 的视图控制器,当我转到 PlayerController 时,它会加载一个音频文件并将其放入 AVAudioPlayer 中,他们的播放按钮是播放 AVAudioPlayer。到目前为止,一切都很好。问题是,如果我离开 PlayerController 并再次转到它,前一个 AVAudioPlayer 的音频仍在播放,在我的 viewWillAppear 方法中,我有此行来停止 AVAudioPlayer 播放,但它不起作用,它不会停止前一个AVAudioPlayer 从播放....我将如何完成我想做的事情?我应该在我的 appDelegate 文件中定义 AVAudioPlayer 并从他们的文件中读取它吗?

这是我的 viewWillAppear 方法:

override func viewWillAppear(_ animated: Bool)
{
    super.viewWillAppear(animated)

    timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: (#selector(PlayerController.updateTimer)), userInfo: nil, repeats: true)

    if(UserDefaults.standard.integer(forKey: "nowPlayingPost") == 0)
        {
            UserDefaults.standard.set(self.postid, forKey: "nowPlayingPost")

            audioSlider.setValue(0, animated: false)

            if(self.audio != nil && (self.audio?.isPlaying)!)
            {
                self.audio?.stop()
            }

        }
        else
        {
            audioSlider.value = Float((self.audio?.currentTime)!)

            self.audioSlider.maximumValue = Float((self.audio?.duration)!)

            self.postid = UserDefaults.standard.integer(forKey: "nowPlayingPost")

            if(self.audio?.isPlaying)!
            {
                self.playButton.setTitle("Stop", for: .normal)
            }
            else
            {

                if(self.audio?.currentTime == 0)
                {
                    self.playButton.setTitle("Play", for: .normal)
                }
                else
                {
                    self.playButton.setTitle("Resume", for: .normal)
                }
            }

        }


    Alamofire.request(audioUrl!).responseData { response in

                    do {

                        self.audio = try AVAudioPlayer(data: response.data!)
                        self.audio?.prepareToPlay()

                        self.audioSlider.maximumValue = Float((self.audio?.duration)!)

                    }catch{

                    }
                }


}

那么我应该在 appDelegate 中定义 AVAudioPlayer 还是使用 UserDefaults 或 CoreData 或其他?这方面的最佳做法是什么?

我认为最好的解决方案是使用 class 单例来控制您的音频功能,这样您就不会创建另一个需要停止且不需要复杂性的 AVAudioPlayer 实例通知中心。您还可以从任何视图控制器访问 Singleton 并添加从 Alamofire 检索音频数据的方法,这样您就不需要通过 segue 或使用 NSUserDefaults 传递数据。

class AudioController {
    static let sharedInstance = AudioController()
    var nowPlayingPost: Int = 0 

    private init(){}

    func playAudioFrom(url: URL){
        // your implementation 
    } 
    // Other methods, stop, pause, etc.
}

视图控制器中的任何位置:

AudioController.sharedInstance.playAudio(url: url)