Search code examples
iosswiftswift3userdefaults

Right way to sync a variable with UserDefaults


I would like to keep a variable sync with UserDefaults directly when I set a value. I've done it like this:

var userId: String {
    get {
        return UserDefaults.standard.string(forKey: kUserIdKey) ?? ""
    }
    set {
        UserDefaults.standard.set(newValue, forKey: kUserIdKey)
    }
}

It is working fine but is it the right way to do it?

If so, what about Array?

var tagsList: [Int] {
    get {
        return (UserDefaults.standard.object(forKey: kTagsList) as? [Int]) ?? [Int]()
    }
    set {
        UserDefaults.standard.set(newValue, forKey: kTagsList)
    }
}

If I add an element tagsList.append(0), is the new value stored in UserDefaults?

Update.

Here is what I have in the playground: enter image description here


Solution

  • Short answer: Yes.

    Long answer: Arrays and Strings are structs in Swift, which semantically make a whole new copy when mutated.

    The newValue in the setter therefore is the resulting array of whatever mutation you applied to the array, whether it being an append or other mutating functions.

    You can easily verify this behavior in a playground like this:

    var array: [Int] {
        get { return [1, 2, 3] }
        set { print(newValue) }
    }
    
    array.append(4)
    // Prints [1, 2, 3, 4]