How is my variable holding two different objects when it's not an array?

Hello,

I have an app that uses JSON data to save and load information. This is how the information is loaded when the app is first opened.

        DispatchQueue.global(qos: .background).async { [weak self] in
            //Get data from "user.data"
            guard let data = try? Data(contentsOf: Self.fileURL) else {
                //code to use test data
                /*#if DEBUG
                                DispatchQueue.main.async {
                                    self?.scrums = DailyScrum.data
                                }
                                #endif*/
                return

            }

            guard let user = try? JSONDecoder().decode(User.self, from: data) else {
                fatalError("Can't decode user data")
            }

            //Set published value to user that was loaded from the file
            DispatchQueue.main.async {
                self?.user = user
            }
        }
    }

There is a struct called Month that is used inside of another struct called User. When the app is open, in the onAppear in ContentView, it runs a function to check the current date. It compares it against what's already saved, and if it's a new month, it will create a new Month struct to replace the current month.

private mutating func newMonth() {

        //Create new month
        month = Month(name: Date().month)

    }

This seems to be working, but not exactly as intended. The new month will be created, but when I open the app it will still show the previous month. I have a TextView that displays the month. I printed the month variable to the console to see what it was reading.

Printed in an HStack this way

let _ = print(user.month)

Output

Month(name: "July", transactions: [], income: 0.0, expenses: 0.0, net: 0.0, saved: 0.0, invested: 0.0, netMargin: 0.0)
Month(name: "June", transactions: [], income: 0.0, expenses: 0.0, net: 0.0, saved: 0.0, invested: 0.0, netMargin: 0.0)

Somehow that month variable is showing two different months in it, June and July. It doesn't make sense to me, because it's not an array and that month variable should be getting replaced due to the newMonth() function. What's going on here? How is it creating a new month, but not overwriting the previous month? Let me know if you need anymore information.

Accepted Reply

The problem was that the JSON data wasn't loaded before I ran the code to check the current date. I moved that code from the onAppear in the ContentView to the following.

DispatchQueue.main.async {
                self?.user = user
                self?.user.checkDate()
           }

The checkDate() function is what called that newMonth() function.

That's why it was printing two different months. It would print the default value for the User struct, and then once the data was loaded, it would print the month that was stored.

Replies

Could you show how User type is defined ?

  • Hey, thanks for your comment. I ended up figuring out the issue. The JSON data wasn't being loaded completely before the app checked the date. So I moved the code from the onAppear to this part.

    DispatchQueue.main.async { self?.user = user self?.user.checkDate() }

    In regards to the issue with it printing June and July, it was because the view was being refreshed so the code to print ran twice. It printed before the JSON data was loaded, and then after it was loaded.

Add a Comment

The problem was that the JSON data wasn't loaded before I ran the code to check the current date. I moved that code from the onAppear in the ContentView to the following.

DispatchQueue.main.async {
                self?.user = user
                self?.user.checkDate()
           }

The checkDate() function is what called that newMonth() function.

That's why it was printing two different months. It would print the default value for the User struct, and then once the data was loaded, it would print the month that was stored.