9

I am trying to check if a UserDefaults Key exists and if not set it to a standard value of my choice, but the answers here on stack overflow didn't help me to get this working.

Essentially I have a couple of UISwitches, one is on and the rest is set to off from the beginning. Now my problem is that I don't know how to save these initial states into UserDefaults when the viewController is loaded and those keys do not exists.

This is how I tried to check if the key for the UISwitch exists and if not set it to true (because that's the state I want it to be) and then check again what the bool for the key is and set the UISwitch to it (this is essentially important when the viewController is opened another time):

func setupSwitches() {
    let defaults = UserDefaults.standard

    //check if the key exists 
    if !defaults.bool(forKey: "parallax") {
        switchParallax.setOn(true, animated: true)
    } 

    //check for the key and set the UISwitch
    if defaults.bool(forKey: "parallax") {
        switchParallax.setOn(true, animated: true)
    } else {
        switchParallax.setOn(false, animated: true)
    } 

}

When the user presses the corresponding button I set the UserDefaults key like this:

@IBAction func switchParallax_tapped(_ sender: UISwitch) {
    let defaults = UserDefaults.standard

    if sender.isOn == true {
        defaults.set(true, forKey: "parallax")
    } else {
        defaults.set(false, forKey: "parallax")
    }
}

This is obviously working, but the problem is in the first code above.

First of all I am not sure how to check if it exists and if not set it to "true" and since the function is called setupSwitches() it is runs every time the viewController is shown.

So I don't know if there is a better way (eg. because of the memory issues) to check if a key exists, if not set it to true and if it already exists get the bool from UserDefaults and set the switch to the right state.

RjC
  • 827
  • 2
  • 14
  • 33

1 Answers1

26

The problem is you can't determine exists with UserDefaults.standard.bool(forKey: key). UserDefaults.standard.object(forKey: key) returns Any? so you can use it to test for nil e.g.

extension UserDefaults {

    static func exists(key: String) -> Bool {
        return UserDefaults.standard.object(forKey: key) != nil
    }

}
Norman
  • 3,020
  • 22
  • 21
  • So this function would return a true if the key exists or false if not, right? So in that case I could I rund an of statement if I get a false and the key does not exists to save a value and set the UISwitch right? – RjC Nov 30 '17 at 20:51
  • 1
    Correct to your first question, I didn't follow the second question. You can also remove the `if` statement in your `switchParallax_tapped()` method and use `defaults.set(sender.isOn, forKey: "parallax")`. – Norman Nov 30 '17 at 20:55
  • Thanks this works kinda and I really like the short method for setting UserDefaults, but for some reason it's not loaded next time. This is what I do: `parallax = UserDefaults.exists(key: "parallax")` and because I understand that this returns a true (if the key exists) or false if not I check with `if parallax == false { defaults.set(true, forKey: "parallax") }` to set it correctly if it was false (key doesn't exist), and then I setup the switch: `switchParallax.setOn(parallax, animated: true)`. But it's now always true when the view is loaded? – RjC Nov 30 '17 at 23:21
  • If it's always true then your `IBAction switchParallax_tapped` isn't getting called. Set a break point at `defaults.set(false, forKey: "parallax")` to make sure it can get set to false. One's it set, it will remain set until your code sets it again or you delete the app. – Norman Dec 01 '17 at 02:58