I have a View Controller called PlayerController, when I goto the PlayerController it load up an audio file and put it into an AVAudioPlayer and their is a play button is play the AVAudioPlayer. So far so good. The problem is if I leave the PlayerController and go to it again the audio from the previous AVAudioPlayer is still playing, in my viewWillAppear method, I have this line to stop the AVAudioPlayer from playing, but its not working, it does not stop the previous AVAudioPlayer from playing....How would I accomplish what I am trying to do? should I define the AVAudioPlayer inside my appDelegate file and read it off their?
This is my viewWillAppear method:
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{
}
}
}
So should I define AVAudioPlayer in appDelegate or use UserDefaults or CoreData or something else? What would be the best practice for this?
I think the best solution would be to use a class Singleton to control your audio functions, in this way you are not creating another instance of an AVAudioPlayer that needs to be stopped and don’t need complexity of Notification Center. You can also access the Singleton from any view controller and add your methods for retrieving audio data from Alamofire so that you don’t need to pass data via segue or use NSUserDefaults.
class AudioController {
static let sharedInstance = AudioController()
var nowPlayingPost: Int = 0
private init(){}
func playAudioFrom(url: URL){
// your implementation
}
// Other methods, stop, pause, etc.
}
Anywhere in your View Controller:
AudioController.sharedInstance.playAudio(url: url)