Swiftui 为什么AVAudioPlayer没有声音?

Swiftui 为什么AVAudioPlayer没有声音?,swiftui,Swiftui,我有一个按钮,可以播放和暂停音频,但我发现下面的代码没有声音。你知道为什么吗?如果我将AVAudioPlayer创建代码片段放入从属函数playAudio(),它可以播放声音,但我不能暂停并继续播放 可复制代码 SwiftUI对在视图结构的初始值设定项中可以执行的操作非常挑剔。更可靠的选择是将加载移动到可观察对象中: class AudioManager : ObservableObject { var audioPlayer : AVAudioPlayer? func

我有一个按钮,可以播放和暂停音频,但我发现下面的代码没有声音。你知道为什么吗?如果我将AVAudioPlayer创建代码片段放入从属函数
playAudio()
,它可以播放声音,但我不能暂停并继续播放

可复制代码
SwiftUI对在视图结构的初始值设定项中可以执行的操作非常挑剔。更可靠的选择是将加载移动到可观察对象中:

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()
            }
    }
}

这在Xcode 12.3和iOS 14上为我播放

为什么使用var audioPlayer:AVAudioPlayer?我们不能只使用var audioPlayer:AVAudioPlayer=AVAudioPlayer()吗?当我们使用可选时,它会使我们额外展开。用我的代码,即使没有文件播放,我们也不会遇到麻烦。因为我们使用的是在负载或游戏中接球。我知道它来自OP,但我想知道它的尊重,因为它在这里看起来习惯上是正确的,而且非常迅速。我们不知道AVAudioPlayer是否会成功加载。仅仅为了避免一个可选的展开,让一个没有功能的播放器在那里是没有意义的。如果初始化时出现问题,则将值设为
nil
更有意义。另外,如果你看一下AVAudioPlayer的空初始值设定项的标题,它说它是由子类使用的——目的不仅仅是用它来创建空白玩家。是的,但我不是要创建空白玩家,AVAudioPlayer的所有目的都是玩,不是吗?所以,若你们同意我的观点,那个么它的所有目的都是玩,我们总是使用,总是使用接球,还有空间使用可选的吗?我的意思是,我们可以使用您的解释,但它会增加用于展开的额外工作。在
loadAudio
之前无法初始化它,因为文件名未知。因此,除非创建空白播放器,否则在此之前它必须是可选的。我已经解释了为什么我认为这是一个惯用的正确决定。我也不认为可选的解包额外的工作——相反,我认为它是类型安全和零校验系统的重要组成部分。
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()
            }
    }
}