I have a stupid issue but for some reason I can’t resolve it. I try to play sound with AVAudioPlayer but can’t hear anything. There are no errors, but still my app is silent. Its built with SwiftUI. This is a piece of code:
struct SoundsListView: View {
var body: some View {
List(Helpers.shared.sounds, id:.self) { item in
Text(item)
Spacer()
Button(action: {
var soundPlayer: AVAudioPlayer?
guard let audioFile: URL = Bundle.main.url(forResource: "Analog watch", withExtension: "mp3") else { return }
do {
soundPlayer = try AVAudioPlayer(contentsOf: audioFile)
print(soundPlayer)
guard let player = soundPlayer else { return }
player.play()
} catch let error {
print("Cannot play sound")
}
}) {
Image(systemName: "play")
} //: BUTTON
}
}
}
There are no errors, also sound files have target membership set.
(What is strange it’s that the same piece of code works with my older project, but written in Swift + Storyboards)
There is no sound generated neither in simulator nor hardware device. Silent mode is off, volume set to max.
I have no idea what’s wrong here.
BTW: This app sends notifications to user and sound is OK. But not in this piece of code
2
Answers
Your
AVAudioPlayer
only exists in the scope of your button action, so it’s deallocated before the sound can play. You need to save it somewhere… I think you could declare it inSoundsListView
as a@State var
, but it may be better to refactor it out of the SwiftUI view entirely.EDIT: You probably also need to set your AVAudioSession, which lets you change playback category and control how your audio interacts with other audio e.g. music playback.
Example:
For me the audio would only work sometimes. I had to ensure that when I declared my audio player in the SwiftUI View, it was an @State object. After I added @State before my property it played every time! I am importing AVKit on a separate file where I have my audio play functions… something like I have pasted below. Lmk if you need more clarification.
//And then this is what I have setup in a separate Swift file.
import AVKit