I can't see the change in the Text object on the ContentView page. However, when I run the same code in .onReceive with print, I can see the change. What's the problem here?
I wanted to manage the state of the game from a different place and the operation of the game from a different place. Is the logic I made wrong?
Enum
enum GameSituation {
case play
}
Game Config
class GameConfig: ObservableObject {
@Published var randomCellValue: Int = 0
@Published var timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
func startGame() {
determineRandomCell()
}
func determineRandomCell() {
randomCellValue = Int.random(in: 0...11)
}
func playSound(soundfile: String, ofType: String) {
if let path = Bundle.main.path(forResource: soundfile, ofType: ofType){
do{
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch {
print("Error")
}
}
}
}
Game Situation
class GameSituations: ObservableObject {
@Published var gameConfig = GameConfig()
func gameSituation(gameSituation: GameSituation) {
switch gameSituation {
case .play:
gameConfig.startGame()
}
}
}
Content View
struct ContentView: View {
@StateObject var gameSituation = GameSituations()
var body: some View {
Text("\(gameSituation.gameConfig.randomCellValue)")
.padding()
.onReceive(gameSituation.gameConfig.timer, perform: { _ in
gameSituation.gameSituation(gameSituation: .play)
print("random: \(gameSituation.gameConfig.randomCellValue)")
})
}
}
You had multi issue I solved all, your first and big issue was, that you are initializing an instance of an ObservableObject but using another one! second one was that you forgot using StateObject of GameConfig in your View, as you can see in your code, you did used StateObject of GameSituations but not GameConfig, if you ask why, because it is Publisher!
My best recommendation: try just use one ObservableObject! using 2 deferent ObservableObject that has binding with together has such a issue that you can see! try organise all your code to one ObservableObject.
enum GameSituation {
case play
}
class GameConfig: ObservableObject {
static let shared: GameConfig = GameConfig() // <<: Here
@Published var randomCellValue: Int = 0
@Published var timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
func startGame() {
determineRandomCell()
}
func determineRandomCell() {
randomCellValue = Int.random(in: 0...11)
}
func playSound(soundfile: String, ofType: String) {
print(soundfile)
}
}
class GameSituations: ObservableObject {
static let shared: GameSituations = GameSituations() // <<: Here
let gameConfig = GameConfig.shared // <<: Here
func gameSituation(gameSituation: GameSituation) {
switch gameSituation {
case .play:
gameConfig.startGame()
}
}
}
struct ContentView: View {
@StateObject var gameSituation = GameSituations.shared // <<: Here
@StateObject var gameConfig = GameConfig.shared // <<: Here
var body: some View {
Text(gameConfig.randomCellValue.description) // <<: Here
.onReceive(gameConfig.timer, perform: { _ in // <<: Here
gameSituation.gameSituation(gameSituation: .play)
print("random: \(gameSituation.gameConfig.randomCellValue)")
})
}
}