Dimi
Dimi

Reputation: 11

Cannot assign to property: 'self' is immutable in SettingView

I am creating a page settingView for saving userdata where I call a class with @ObservedObject. And I also made some func in the settingView page for load and save the userdata. But there I get the error "Cannot assign to property: 'self' is immutable in SettingView". How can I solve this.

class UserData: ObservableObject, Codable {
    @Published var name = ""
    @Published var firstname = ""
    @Published var email = ""
}

struct SettingsView: View {
    @ObservedObject var userdata = UserData()

var body: some View {
        
        NavigationView{
            Form {
                Section(header: Text("User")){
                    TextField("Name", text: $userdata.name)
                    TextField("Firstname", text: $userdata.firstname)
                    TextField("Email...", text: $userdata.email)
                   //more code
                }
                Section{
                    Button(action: {
                        self.saveData()
                        self.showingAlert = true
                    }){
                        Text("Save")
                    }
            }
        }

        .onAppear(perform: {
            self.loadData()
        })
    }
    
    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }
    
    func loadData() {
        let filename = getDocumentsDirectory().appendingPathComponent("SavedData")

        do {
            let data = try Data(contentsOf: filename)
            userdata = try JSONDecoder().decode(UserData.self, from: data) <-- error on userdata
            print("File is loaded")
        } catch {
            print("Unable to load saved data.")
        }
    }
}

Upvotes: 0

Views: 2463

Answers (1)

Rob Napier
Rob Napier

Reputation: 299345

You cannot assign to an ObservedObject. An ObservableObject is an object that modifies itself, and when it does, it notifies observes. So typically you would implement this as userData.load(from: filename) and letting UserData do all the work, rather than reassigning userData. To make that work properly, you'll need to wrap up the struct that you're decoding (it can't replace itself). So your ObservableObject would likely be something like "DataStore" that holds a UserData.

Upvotes: 1

Related Questions