Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Help with NSUserDefaults

I am having trouble with NSUserDefaults. Here is the code:

var money = 0
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setValue(money, forKey: "money")
userDefaults.synchronize() 

and then to read it:

if let score = userDefaults.valueForKey("score") {
   moneyLabel.text = "Money:\(money)"
}
else {
    money = 0
}

What happens is that when I load the money number it appears on the label like I wanted to but, when more money was added the number reset to zero. How do I make it so that any extra money made is added to the label instead of it reseting to zero?

2 Answers

Michael Hulet
Michael Hulet
47,913 Points

Wait, I think I just noticed your problem. You're accessing a value with a different key than you're setting it with. This line:

userDefaults.setValue(money, forKey: "money")

needs to use the same String as this line:

if let score = userDefaults.valueForKey("score") {

Here's a fixed version of my 2nd referenced line:

if let score = userDefaults.valueForKey("money") {

When you use this alongside my first answer (preferably the 2nd part of my first answer, as that one writes to the disk less frequently), your problems should go away

That seems to have fixed the problems. Thanks!

Michael Hulet
Michael Hulet
47,913 Points

It sounds like you're setting money and storing it in NSUserDefaults once, whereas you should update its NSUserDefaults representation every time money changes, like this:

var money{
    didSet{
        let userDefaults = NSUserDefaults.standardUserDefaults()
        userDefaults.setValue(money, forKey: "money")
        userDefaults.synchronize()
    }
}

Alternatively, you can save the current value of your money variable whenever your view is about to disappear, like this:

override func viewWillDisappear(animated: Bool) -> Void{
    super.viewWillDisappear(animated)
    let userDefaults = NSUserDefaults.standardUserDefaults()
    userDefaults.setValue(money, forKey: "money")
    userDefaults.synchronize()
}

I have tried both but, it has the same problem that I had with my code before.

Michael Hulet
Michael Hulet
47,913 Points

Could you post the entire content of your class, then?

I'd prefer not to since the class this part is apart of, is a class within an app I would like to release. Is there any other way to solve it?

Michael Hulet
Michael Hulet
47,913 Points

It'd be pretty hard. No one's going to steal your app (it'd be impossible to with just one class). In fact, open-sourcing is a really popular thing in software development. I put all of my code on my GitHub. In fact, the only app I have on the App Store has the entirety of its code posted for anyone to see and use in a repository on my GitHub. It's an entirely safe and frequently encouraged thing to do