0

I have created a custom class (as an ObservedObject since I need to share this data). Everything works but when I force close the app the data resets and I have not found any way to save it to UserDefaults. (Trying to save normally as an object crashed the app).

How can I save this data? (When pressing the button in SettingsView)

First time asking here.

---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!
    }

--- SettingsView ---

import SwiftUI

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

Thanks.

  • 1
    "How can I" is very broad. This is an easy task, especially in Xcode 12 beta where a value basically saves itself. What part do you have trouble with? Saving to user defaults has been explained many times here. Did you search? You can save an arbitrary object's properties by making the object conform to Codable; that would be trivial for your ProgressData. See https://stackoverflow.com/questions/44876420/save-struct-to-userdefaults/45909055#45909055 for example. – matt Jul 18 '20 at 22:45
  • Hey, thanks for answering. Currently I don’t know what is the best way to save classes but I have some experience with user defaults so I will try what you suggested. Couldn’t find it myself... – Ariel Turjeman Jul 18 '20 at 23:44
  • Answer: https://stackoverflow.com/questions/57611658/swiftui-how-to-persist-published-variable-using-userdefaults – Ariel Turjeman Sep 25 '20 at 15:19

1 Answers1

1

In order to do so, all you have to do is make sure your custom class is comforting the Codable protocol.

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
}

Next, you need to save it to UserDefault like that:

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")
            }
        })

    }

}

When you want to pull your saved data from UserDefaults, all you have to do it:

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`
    }
}

You can read a bit more about it, in this wonderful article

Tal Cohen
  • 1,308
  • 10
  • 20