-2

I am a new coder. I am trying to program a feature in a game so that if it is the first time the user has logged into the app, the user will be presented with a tutorial; however, it doesn't seem to save.

It does change, but it just doesn't save.

@main
struct Fixing_The_Tutorial_And_IntroApp: App {
    @StateObject var gameData = ResourcePool()
    @State var returnedData = ResourcePoolData()
    var body: some Scene {
        WindowGroup {
            ContentView(gameData: gameData)
                .onAppear{
                    returnedData = load(key: key) ?? ResourcePoolData()
                    gameData.setValue(resourcePoolData: returnedData)
                }
        }
    }
}
struct ContentView: View {    @ObservedObject var gameData: ResourcePool
    @ObservedObject var gameCon : GameCondition = GameCondition.shared
    var body: some View {
        VStack {
            Button("I've seen it"){
                gameData.setSeen()
            }
            if !gameCon.checkViewedTutorial() {
                Rectangle().frame(width: 100, height: 100)
            }
        }
        .padding()
    }
}
func save<T: Identifiable & Codable>(items: T, key: String) {
    let encoder = JSONEncoder()
    if let encoded = try? encoder.encode(items) {
        let defaults = UserDefaults.standard
        defaults.set(encoded, forKey: key)
        print("Saving \(key)")
    }
}
func load<T: Identifiable & Codable>(key: String) -> T? {
    guard let data = UserDefaults.standard.object(forKey: key) as? Data else { return  nil }
    
    let decoder = JSONDecoder()
    if let dataArray = try? decoder.decode(T.self, from: data) {
        print("Loading \(key)")
        return dataArray
    }
    return nil
}
struct ResourcePoolData : Codable & Identifiable {
    var id = UUID()
    var gameConData : GameConditionModel
    init(resourcePool : ResourcePool){
        self.gameConData = resourcePool.gameConData
    }
    init(){
        gameConData = GameConditionModel()
    }
}
class GameCondition : ObservableObject {
    @Published var data : GameConditionModel
    static let shared = GameCondition(data: GameConditionModel())
    private init(data: GameConditionModel) {
            self.data = data
        }
    func checkViewedTutorial()-> Bool {
        return data.hasViewedTutorial
    }
    func reset(){
        data.reset()
    }
    
}
struct GameConditionModel : Identifiable, Codable {
    var id = UUID()
    var hasViewedTutorial = false
    mutating func reset(){
        hasViewedTutorial = false
    }
}
let key = "game data"
class ResourcePool : ObservableObject {
    @Published var gameConData : GameConditionModel = GameConditionModel()
    @Published var gameCon : GameCondition = GameCondition.shared
    func setValue(resourcePoolData: ResourcePoolData) {
        self.gameConData = resourcePoolData.gameConData
    }
    func reset() {
        GameCondition.shared.reset()
    }
    func setSeen(){
        gameCon.data.hasViewedTutorial = true
        save(items: ResourcePoolData(resourcePool: self), key: key)
//print("hasViewedTutorial: \(gameCon.data.hasViewedTutorial)")
//Loading game data
//Saving game data
//hasViewedTutorial: true
    }

}

I've simplified the code to the only moving parts. I've thrown it into Bing, but this is what it gives me.

The code you provided seems to be missing the save function call in the setSeen method of the ResourcePool class. This means that the hasViewedTutorial property is not being saved to UserDefaults when the button is pressed. You can fix this by adding the following line to the setSeen method:

save(items: ResourcePoolData(resourcePool: self), key: key)

This will save the current state of the ResourcePoolData object to UserDefaults using the provided key. Once this change is made, pressing the button should save the value of hasViewedTutorial to UserDefaults. Let me know if this helps!

But that simply, is not true.

I've also made sure to check whether the thing was being saved in

    func setSeen(){
        gameCon.data.hasViewedTutorial = true
        save(items: ResourcePoolData(resourcePool: self), key: key)
        print("hasViewedTutorial: \(gameCon.data.hasViewedTutorial)")
}

And this was what I got

Loading game data, Saving game data, hasViewedTutorial: true

So I'm a bit at a loss. I don't see anything that can be going wrong.

  • I'm a new coder asking for help. I'm not asking for a grade. – Conner Yoon Aug 23 '23 at 14:04
  • I'm helping you ask the question better and thus get better help. I'm also teaching you how to solve the problem: make a vastly simplified version of the problem. – matt Aug 23 '23 at 14:09
  • Aight, will do. Will have to work on it a bit later, will provide updates. Thanks, I thought you were just saying my code was bad. My bad. – Conner Yoon Aug 23 '23 at 14:24

0 Answers0