视图无法识别 @EnvironmentObject 的实例。

huangapple go评论78阅读模式
英文:

View not recognizing instance of @EnvironmentObject

问题

我正在处理我的应用程序中的音频播放器部分,而在播放器视图中,我有一个简单的if语句检查。它检查是否存在audioManager.player的实例,如果存在一个实例,则创建vstacks/hstacks等等。

由于某种原因,它在这个检查上失败了,并且说没有audioManager的实例,而没有加载适当的视图。它在模拟器上不起作用,我在应用程序启动时创建了AudioManager()的实例,并且在预览中也不起作用,我在那里直接注入了实例,这毫无道理。

我注意到.autoconnect()是白色的?我不确定这是否意味着它没有识别到某些内容或者是什么情况。

这是视图播放器的代码:

import SwiftUI

struct listeningActivity: View {
    @EnvironmentObject var audioManager: AudioManager
    var listeningActivityVM: ListeningActivityViewModel
    
    @State private var value: Double = 0.0
    @State private var isEditing: Bool = false
    
    let timer = Timer.publish(every: 0.5, on: .main, in: .common)
        .autoconnect()
    
    var body: some View {
        ZStack{
            Image("pot")
                .resizable()
                .scaledToFill()
                .frame(width: UIScreen.main.bounds.width)
                .ignoresSafeArea()
            
            VStack(spacing: 32) {
                HStack {
                    Button {
                        
                    } label: {
                        Image(systemName: "xmark.circle.fill")
                            .font(.system(size:36))
                            .foregroundColor(.white)
                    }
                    
                    Spacer()
                }
                
                Text("pasta carbonoara")
                    .font(.title)
                    .foregroundColor(.white)
                
                Spacer()
                
                if let player = audioManager.player {
                    VStack(spacing: 5){
                        
                        Slider(value: $value, in: 0...player.duration) { editing
                            in
                            
                            print("editing", editing)
                            isEditing = editing
                            
                            if !editing {
                                player.currentTime = value
                            }
                        }
                        .scaleEffect(1.5)
                        .frame(width: 200, height: 20)
                        .tint(.orange)
                        .padding(.top, 50)
                        
                        HStack{
                            Text(DateComponentsFormatter.positional
                                .string(from: player.currentTime) ?? "0:00")
                            
                            Spacer()
                            
                            Text(DateComponentsFormatter.positional
                                .string(from: player.duration - player.currentTime) ?? "0:00")
                            
                        }.padding([.leading, .trailing], 40)
                            .padding(.top, 15)
                    }
                    
                    HStack{
                        PlaybackControlButton(systemName: "repeat") {
                            
                        }
                        Spacer()
                        PlaybackControlButton(systemName: "gobackward.10") {
                            
                        }
                        Spacer()
                        PlaybackControlButton(systemName: player.isPlaying ? "pause.circle.fill" : "play.circle.fill", fontSize: 44) {
                            audioManager.playPlause()
                        }
                        Spacer()
                        PlaybackControlButton(systemName: "goforward.10") {
                            
                        }
                        Spacer()
                        PlaybackControlButton(systemName: "stop.fill") {
                            
                        }
                    }
                }
                
            }
            .padding(20)
        }
        .onAppear{
            audioManager.startPlayer(track: listeningActivityVM.audioAct.track)
        }
        .onReceive(timer) { _ in
            guard let player = audioManager.player, !isEditing else {return}
            value = player.currentTime
        }
    }
}

struct listeningActivity_Previews: PreviewProvider {
    static let listeningActivityVM  = ListeningActivityViewModel(audioAct: audioActivty.data)
    static var previews: some View {
        listeningActivity(listeningActivityVM: listeningActivityVM)
            .environmentObject(AudioManager())
    }
}

这是我的AudioManager()代码:

import Foundation
import AVKit

final class AudioManager: ObservableObject{
    
    var player: AVAudioPlayer?
    
    func startPlayer(track: String) {
        guard let url = Bundle.main.url(forResource: track, withExtension: "wav") else {
            print("Resource not found: \(track)")
            return
        }
        
        do {
            try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
            try AVAudioSession.sharedInstance().setActive(true)
            player = try AVAudioPlayer(contentsOf: url)
            
            player?.play()
        }catch{
            print("Fail to initialize player", error)
        }
    }
    
    func playPlause() {
        guard let player = player else {
            print("Instance of audio player not found")
            return
        }
        
        if player.isPlaying {
            player.pause()
        }else {
            player.play()
        }
    }
}

希望这些信息对你有所帮助。如果有任何问题,请随时提出。

英文:

I'm working on the audio player portion of my app and inside the player view, I have a simple if statement check. It looks to make sure there is an instance of the audioManager.player and if there is one, it created the vstacks/hstacks etc.

For some reason, it is failing on that check and saying there is no instance of the audioManager and not loading the appropriate view. Its not working with the simulator where I create the instance of AudioManager() on app start up and its not working in the preview either where I'm directly injecting the instance which makes no sense.

I do notice that .autoconnect() is white? I'm not sure if that means its not recognizing something or what.

Here is the code for the view player

import SwiftUI
struct listeningActivity: View {
@EnvironmentObject var audioManager: AudioManager
var listeningActivityVM:ListeningActivityViewModel
@State private var value: Double = 0.0
@State private var isEditing: Bool = false
let timer = Timer.publish(every: 0.5, on: .main, in: .common)
.autoconnect()
var body: some View {
ZStack{
Image("pot")
.resizable()
.scaledToFill()
.frame(width: UIScreen.main.bounds.width)
.ignoresSafeArea()
VStack(spacing: 32) {
HStack {
Button {
} label: {
Image(systemName: "xmark.circle.fill")
.font(.system(size:36))
.foregroundColor(.white)
}
Spacer()
}
Text("pasta carbonoara")
.font(.title)
.foregroundColor(.white)
Spacer()
if let player = audioManager.player {
VStack(spacing: 5){
Slider(value: $value, in: 0...player.duration) { editing
in
print("editing", editing)
isEditing = editing
if !editing {
player.currentTime = value
}
}
.scaleEffect(1.5)
.frame(width: 200, height: 20)
.tint(.orange)
.padding(.top, 50)
HStack{
Text(DateComponentsFormatter.positional
.string(from: player.currentTime) ?? "0:00")
Spacer()
Text(DateComponentsFormatter.positional
.string(from: player.duration - player.currentTime) ?? "0:00")
}.padding([.leading, .trailing], 40)
.padding(.top, 15)
}
HStack{
PlaybackControlButton(systemName: "repeat") {
}
Spacer()
PlaybackControlButton(systemName: "gobackward.10") {
}
Spacer()
PlaybackControlButton(systemName: player.isPlaying ? "pause.circle.fill" : "play.circle.fill", fontSize: 44) {
audioManager.playPlause()
}
Spacer()
PlaybackControlButton(systemName: "goforward.10") {
}
Spacer()
PlaybackControlButton(systemName: "stop.fill") {
}
}
}
}
.padding(20)
}
.onAppear{
audioManager.startPlayer(track: listeningActivityVM.audioAct.track)
}.onReceive(timer) { _ in
guard let player = audioManager.player, !isEditing else {return}
value = player.currentTime
}
}
}
struct listeningActivity_Previews: PreviewProvider {
static let listeningActivityVM  = ListeningActivityViewModel(audioAct: audioActivty.data)
static var previews: some View {
listeningActivity(listeningActivityVM: listeningActivityVM)
.environmentObject(AudioManager())
}
}

This is my AudioManager() code

import Foundation
import AVKit
final class AudioManager: ObservableObject{
var player: AVAudioPlayer?
func startPlayer(track: String) {
guard let url = Bundle.main.url(forResource: track, withExtension: "wav") else {
print("Resource not found: \(track)")
return
}
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url)
player?.play()
}catch{
print("Fail to initialize player", error)
}
}
func playPlause() {
guard let player = player else {
print("Instance of audio player not found")
return
}
if player.isPlaying {
player.pause()
}else {
player.play()
}
}
}

答案1

得分: 1

我回头看了一下我正在参考的YouTube教程,幸运的是一些人遇到了相同的问题,并在评论中解决了这个问题。

我需要在我的var player: AVAudioPlayer?声明前面添加@Published属性包装器。

英文:

I looked back at the YouTube tutorial I was following and luckily some people were having the same issue and solved the problem in the comments.

I needed to add the @Published property wrapper in front of my var player: AVAudioPlayer? declaration.

huangapple
  • 本文由 发表于 2023年6月9日 02:22:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76434698.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定