5

Is there a more elegant way to increment a counter stored in user defaults?

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(defaults.integerForKey("counter")+1, forKey: "counter")
Henrik
  • 3,908
  • 27
  • 48
  • 1
    No, it isn't. But maybe you could use a local counter and write to user defaults when leaving a controller or quitting the app. – vadian Feb 13 '16 at 12:24

3 Answers3

10

No but if you do this a lot it might make a nice extension, something like this.

extension NSUserDefaults {
    class func incrementIntegerForKey(key:String) {
        let defaults = standardUserDefaults()
        let int = defaults.integerForKey(key)
        defaults.setInteger(int+1, forKey:key)
    }
}

Usage like this

NSUserDefaults.incrementIntegerForKey("counter")
Wez
  • 10,555
  • 5
  • 49
  • 63
  • I continue to be impressed with the possibilities of extensions. I went for a version of this, which I'll post as a separate answer. – Henrik Feb 14 '16 at 16:30
  • I would add a `defaults.synchronize()` statement at the end of this function. If one wants to perform several such operations in shorter amount of time, there is no guarantee that the value is immediately updated. – Vlad Rusu Jun 17 '20 at 17:33
5

This is the same as the solution offered by Wezly, but it reuses my global defaults object and and allows me to modify the value.

extension NSUserDefaults {
    func incrementIntegerForKey(key:String, by: Int) {
        let int = integerForKey(key)
        setInteger(int + by, forKey:key)
    }
}

Used like so (assuming you've defined defaults elsewhere):

defaults.incrementIntegerForKey("counter", by: -3)
Henrik
  • 3,908
  • 27
  • 48
1
extension UserDefaults {
    class func incrementIntegerForKey(key: String) -> Int {
        let defaults = UserDefaults()
        let int = defaults.integer(forKey: key)
        defaults.setValue(int + 1, forKey: key)
        return int + 1
    }
}

Swift 5.1 also with return value for current increment

Ahmed Safadi
  • 4,402
  • 37
  • 33