Reputation: 1058
I got one button which can play and pause the audio, but I found the following code has no sound. Do you know why? If I put the AVAudioPlayer create code snippet in a dependent function playAudio()
, it can play the sound but I cannot pause and continue playing.
import SwiftUI
import AVFoundation
struct ContentView: View {
var shortname: String
var id: Int
@State var audioPlayer: AVAudioPlayer?
init(shortname: String="rs", id: Int=1) {
self.shortname = shortname
self.id = id
let fileName = self.shortname.lowercased() + "-" + String(id)
guard let path = Bundle.main.path(forResource: fileName, ofType: "mp3") else {
print("[shark]", fileName + "is not found")
return
}
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer?.play()
} catch {
print("[shark], audioPlayer cannot load", path, error)
}
}
var body: some View {
Text("good")
.onAppear {
audioPlayer?.play()
}
}
}
Upvotes: 1
Views: 598
Reputation: 52347
SwiftUI is picky about what you can do in an initializer for a View struct like this. A more reliable option is to move the loading into an ObservableObject:
class AudioManager : ObservableObject {
var audioPlayer : AVAudioPlayer?
func loadAudio(filename: String) {
guard let path = Bundle.main.path(forResource: filename, ofType: "mp3") else {
print("[shark]", filename + "is not found")
return
}
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
} catch {
print("[shark], audioPlayer cannot load", path, error)
}
}
func playAudio() {
audioPlayer?.play()
}
}
struct ContentView: View {
var shortname: String = ""
var id: Int = 0
@ObservedObject var audioManager = AudioManager()
var body: some View {
Text("good")
.onAppear {
let fileName = self.shortname.lowercased() + "-" + String(id)
audioManager.loadAudio(filename: fileName)
audioManager.playAudio()
}
}
}
This plays for me on Xcode 12.3 and iOS 14
Upvotes: 2