0

I have a class that saves the state of something, in my case some variable of the ViewController, but sometimes it loads wrong or old data, but I can't figure out why.

Maybe somebody can have a look of my code and see if it makes sense.

class TopFlopState: Codable, PersistenceState {

    var group: Groups = .large {
        didSet {
            save()
        }
    }
    var base: Bases = .usd {
        didSet {
            save()
        }
    }
    var valueOne: StatIntervalBaseModel = StatIntervalBaseModel(stat: "ppc", interval: "24h", base: "usd") {
        didSet {
            save()
        }
    }

    init(){
        let savedValues = load()
        if savedValues != nil {
            self.group = savedValues!.group
            self.base = savedValues!.base
            self.valueOne = savedValues!.valueOne
        }
    }
}

This is the PersistenceState protocol:

/**
Saves and Loads the class, enum etc. with UserDefaults.
Has to conform to Codable.
Uses as Key, the name of the class, enum etc.

 */
protocol PersistenceState  {
}


extension PersistenceState where Self: Codable {


    private var keyUserDefaults: String {
        return String(describing: self)
    }

    func save() {
        saveUserDefaults(withKey: keyUserDefaults, myType: self)
    }

    func load() -> Self? {
        return loadUserDefaults(withKey: keyUserDefaults)
    }

    private func saveUserDefaults<T: Codable>(withKey key: String, myType: T){
        do {
            let data = try PropertyListEncoder().encode(myType)
            UserDefaults.standard.set(data, forKey: key)
            print("Saved for Key:", key)
        } catch {
            print("Save Failed")
        }
    }

    private func loadUserDefaults<T: Codable>(withKey key: String) -> T? {
        guard let data = UserDefaults.standard.object(forKey: key) as? Data else { return nil }
        do {
            let decoded = try PropertyListDecoder().decode(T.self, from: data)
            return decoded
        } catch {
            print("Decoding failed for key", key)
            return nil
        }
    }
}

If a value gets set to the value it should automatically save, but like I set sometimes it saves the right values but loads the wrong ones...

Renzo Tissoni
  • 642
  • 9
  • 21
PaFi
  • 888
  • 1
  • 9
  • 24

1 Answers1

0

In my opinion, It return the cache. Because in Apple official documentation, it state

UserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default value

Maybe you can change the flow, when to save the data. In your code show that you call save() 3 times in init().

Hendra Halim
  • 22
  • 1
  • 5
  • when it is initialising it does not call didSet, so I do not think thats the problem. Does the cache not get reseted after the app does a restart? Thanks for your answer. Is there a way to not return the cache but always to return the saved values? – PaFi Dec 14 '18 at 10:19
  • I tried to set the key to an actual string but did not get ride of the problem – PaFi Dec 14 '18 at 10:33
  • I also wrapped it around the main thread like it is described here: https://stackoverflow.com/questions/41302015/userdefaults-is-not-saved-with-swift-3 did not help either... do you have any other ideas? – PaFi Dec 14 '18 at 10:35
  • https://stackoverflow.com/questions/21868315/nsuserdefaults-not-saving it also could be that it has not saved yet, well I will make some tests. – PaFi Dec 14 '18 at 11:03