AVAudioPlayer play() method play audio for 1 secs and stopped

Hi, I am trying to implement outgoing call ringtone in swift 5.0 where I am using AVAudioPlayer. I have loaded the audio file (mp3), set numberOfLoops to -1 and called prepareToPlay() in init() of my class. Checked PrepareToPlay() method returns true.

When calling play(), it play the ringtone for one sec and stopped (even thought the ringtone duration in one loop is 7secs) but stop() is not called. When I introduce 100ms delay to play the ringtone for first time play, then it is playing continuously until stopped and second time onwards no issue in playing without delay. This is the case for latest iPhone. But when I tested the same code in old iPhone like 6s then getting same issue. In that case I have to introduce more delay as it is old hardware.

In my case, the object of the ringtone player is created and play() is called immediately.

Is this hardware delay (what I suspected) or may be something else expected even prepareToPlay() returns true? Or Am I not handling the AVAudioPlayer object properly?

These symptoms could be occurring if your AVAudioPlayer is being deallocated during playback. The audio that you hear might depend on how much audio data has already been buffered when the deallocation occurs.

When you create your AVAudioPlayer, do you keep an owning (strong) reference to it in (say) an instance variable for the entire duration of playback? Assigning the audio player reference to a local variable isn't going to work, since it will be deallocated when the local scope is exited. Or, might there be something that's discarding the player early?

Thank you very much for your reply. I have a strong reference for the AVAudioPlayer.

    @objc public func playRingtone() {
        guard let isPlaying = audioPlayer?.isPlaying, !isPlaying else { return }

        if isFirstTimePlay {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                self.audioPlayer?.play()
            }
            isFirstTimePlay = false
        } else {
            audioPlayer?.currentTime = 0
            audioPlayer?.play()
        }
    }

This is my code which is working fine for old (iPhone 6s)and new iPhone (iPhone 12). When I reduce the delay to 0.1s, then it is working fully for new iPhone but not working for old iPhone (playing only 1 sec audio and stopped). The same behaviour is happening for new iPhone if I remove the delay completely. Even without having delay, from second call onwards when my object already alive after first call, the ringtone play properly. The issue is happening when object created and called the play method immediately in first call. Any idea?

AVAudioPlayer play() method play audio for 1 secs and stopped
 
 
Q