Проблемы с сохранением данных в UserDefaults

Я пытаюсь сохранить дату в UserDefaults. У меня есть структура, массив которой я собираюсь сохранить:

struct Habit: Identifiable, Codable {
    var id = UUID()   
    var name: String
    var comments: String
}

Затем в представлении у меня есть кнопка, позволяющая сохранить новую привычку в массиве привычек и поместить ее в UserDefaults:

struct AddView: View {
    @State private var newHabit = Habit(name: "", comments: "")
    @State private var name: String = ""
    let userData = defaults.object(forKey: "userData") as? [Habit] ?? [Habit]()
    @State private var allHabits = [Habit]()
    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Habit name")) {
                    TextField("Jogging", text: $newHabit.name)
                }
                Section(header: Text("Description")) {
                    TextField("Brief comments", text: $newHabit.comments)
                }
                
            }
            .navigationBarTitle("New habit")
            .navigationBarItems(trailing: Button(action: {
                allHabits = userData
                allHabits.append(newHabit)
                defaults.set(allHabits, forKey: "userData")
            }) {
                addButton
            })
        }
    }
}

Когда я нажимаю кнопку, мое приложение вылетает с этой цепочкой: Thread 1: "Attempt to insert non-property list object (\n \"HabitRabbit.Habit(id: 574CA523-866E-47C3-B56B-D0F85EBD9CB1, name: \\\"Wfs\\\", comments: \\\"Sdfdfsd\\\")\"\n) for key userData"

Что я сделал не так?


person Philipp Lazarev    schedule 25.01.2021    source источник


Ответы (1)


Принятие Codable не делает список свойств объекта совместимым как таковой, вы должны кодировать и декодировать объект в Data и из него.

Что-то вроде этого

func loadData() -> [Habit]
    guard let userData = defaults.data(forKey: "userData") else { return [] }
    return try? JSONDecoder().decode([Habit].self, from: userData) ?? []
}

func saveData(habits : [Habit]) {
    guard let data = try? JSONEncoder().encode(habits) else { return }
    defaults.set(data, forKey: "userData")
}
person vadian    schedule 25.01.2021
comment
Большое спасибо! - person Philipp Lazarev; 27.01.2021