SwiftUI - Как сохранить данные пользовательского класса в UserDefaults?

Я создал собственный класс (как ObservedObject, так как мне нужно поделиться этими данными). Все работает, но когда я принудительно закрываю приложение, данные сбрасываются, и я не нашел способа сохранить их в UserDefaults. (Попытка сохранить в обычном режиме как объект вызвала сбой приложения).

Как я могу сохранить эти данные? (При нажатии кнопки в SettingsView)

Впервые спрашиваю здесь.

--- MainView ---

import SwiftUI

class ProgressData:  ObservableObject {
    @Published var licenseDate: Date = Date()
    @Published var dayProgressValue: Float = 0.00
    @Published var nightProgressValue: Float = 0.00
    @Published var newDriverProgressValue: Float = 0.00
}

struct MainView: View {
    let defualts = UserDefaults.standard
    @ObservedObject var data = ProgressData()
    
    var body: some View {
       // App Code Here!
    }

--- НастройкиПросмотр ---

import SwiftUI

struct SettingsView: View {
    @ObservedObject var data: ProgressData
    
    
    var body: some View {
         Button(action: {
            // What to do in order to save it here?
         })
    }

Спасибо.


person Ariel Turjeman    schedule 18.07.2020    source источник
comment
Как я могу очень широко. Это простая задача, особенно в бета-версии Xcode 12, где значение в основном сохраняется. С какой частью у вас проблемы? Здесь много раз объяснялось сохранение значений по умолчанию. Вы искали? Вы можете сохранить свойства произвольного объекта, сделав объект совместимым с Codable; это было бы тривиально для вашего ProgressData. См. stackoverflow.com/questions/44876420/ например.   -  person matt    schedule 19.07.2020
comment
Привет, спасибо, что ответили. В настоящее время я не знаю, как лучше всего сохранять классы, но у меня есть некоторый опыт работы с пользовательскими настройками по умолчанию, поэтому я попробую то, что вы предложили. Сам не нашел ...   -  person Ariel Turjeman    schedule 19.07.2020
comment
Ответ: https://stackoverflow.com/questions/57611658/swiftui-how-to-persist-published-variable-using-userdefaults   -  person Ariel Turjeman    schedule 25.09.2020


Ответы (1)


Для этого все, что вам нужно сделать, это убедиться, что ваш пользовательский класс поддерживает протокол Codable.

class ProgressData:  ObservableObject, Codable {
    @Published var licenseDate: Date = Date()
    @Published var dayProgressValue: Float = 0.00
    @Published var nightProgressValue: Float = 0.00
    @Published var newDriverProgressValue: Float = 0.00
}

Далее вам нужно сохранить его в UserDefault вот так:

import SwiftUI

struct SettingsView: View {
    @ObservedObject var data: ProgressData

    var body: some View {

        Button(action: {
            let encoder = JSONEncoder()
            if let encoded = try? encoder.encode(data) {
                UserDefaults.standard.set(encoded, forKey: "saved_data")
            }
        })

    }

}

Если вы хотите получить сохраненные данные из UserDefaults, все, что вам нужно сделать:

if let data = defaults.object(forKey: "saved_data") as? Data {
    let decoder = JSONDecoder()
    if let savedData = try? decoder.decode(ProgressData.self, from: data) {
        // Do wantever you want with `savedData`
    }
}

Вы можете прочитать об этом немного больше в этом замечательная статья

person Tal Cohen    schedule 19.07.2020
comment
Привет, спасибо, что ответили. Похоже, что @Published не может быть закодирован или декодирован. Пробовал без ошибок и без ошибок. - person Ariel Turjeman; 19.07.2020