Search code examples
iosswiftxcode8userdefaults

Values replacing each other using UserDefaults


I have an app where I time myself and see how long it takes me to complete a bunch of questions. I have the time transferred to another VC and displayed in a label. I have it being stored by pressing a button but when i have a new variable(time) it replaces it. How do i store an Array of values and that can be displayed in a label?

Button to save the value:

@IBAction func saveScore(_ sender: Any) {
    scoreLabel.text = label.text
    UserDefaults.standard.set(scoreLabel.text, forKey: "score")
}

The code that permanently holds the data:

override func viewDidAppear(_ animated: Bool) {
    if let x = UserDefaults.standard.object(forKey: "score") as? String {
        scoreLabel.text = x
    }
}

My scoreLabel displays all my scores and label shows the time you just got.


Solution

  • Use the following extentions on UserDefaults to store an array of times:

    extension UserDefaults {
        var times: [String] {
            get {
                if let times = UserDefaults.standard.object(forKey: "times") as? [String] {
                    return times
                } else {
                    return []
                }
            }
            set {
                UserDefaults.standard.set(newValue, forKey: "times")
            }
        }
    }
    

    While you don't need to extend UserDefaults, using extension can simplify a bit working with persisted values and it makes the code cleaner.

    Then at the point where you show the data, use the following line to access the array:

    let arrayOfTimes = UserDefaults.standard.times
    scoreLabel.text = "\(arrayOfTimes)" // or any other formatting you'd like
    

    And instead of setting the times to persist a new score, just add the new score to the array, e.g.:

    // This will not only add the scoreLabel.text to the array, but also persists it
    UserDefaults.standard.times.append(scoreLabel.text)