How to deal with non-optional values in NSUserDefaults in Swift

To get a value from NSUserDefaults I would do something like this:

let userDefaults = NSUserDefaults.standardUserDefaults()
if let value = userDefaults.objectForKey(key) {
    print(value)
}

However, these methods do not return optionals:

  • What is equivalent of “dispatch_apply” in Swift 3?
  • Resize inputAccessoryView dynamically in iOS 8
  • No suitable mapping model found for core data migration
  • Xcode or native-react latches on to a wrong root directory to search for .ios.js file
  • How can I support both iOS 4.X SDK and iOS 5 SDK in my iPhone app?
  • Verifying user is authenticated using AWS IOS SDK
    • boolForKey (defaults to false if not set)
    • integerForKey (defaults to 0 if not set)
    • floatForKey (defaults to 0.0 if not set)
    • doubleForKey (defaults to 0.0 if not set)

    In my app I want to used the saved value of an integer if it has been previously set. And if it wasn’t previously set, I want to use my own default value. The problem is that 0 is a valid integer value for my app, so I have no way of knowing if 0 is a previously saved value or if it is the default unset value.

    How would I deal with this?

    5 Solutions Collect From Internet About “How to deal with non-optional values in NSUserDefaults in Swift”

    Register the user defaults in AppDelegate, the best place is awakeFromNib or even init. You can provide custom default values for every key.

     override init()
     {
       let defaults = NSUserDefaults.standardUserDefaults()
       let defaultValues = ["key1" : 12, "key2" : 12.6]
       defaults.registerDefaults(defaultValues)
       super.init()
     }
    

    Then you can read the values from everywhere always as non-optionals

    let defaults = NSUserDefaults.standardUserDefaults()
    myVariable1 = defaults.integerForKey("key1")
    myVariable2 = defaults.doubleForKey("key2")
    

    I just found something that seems to work. I can continue to use objectForKey (which does return an optional) and use as? to optionally cast it to an Int.

    if let myInteger = userDefaults.objectForKey(key) as? Int {
        print(myInteger)
    } else {
        print("no value was set for this key")
    }
    

    The solutions for Bool, Float, and Double would work the same way.

    You could register defaults for your app that aren’t legitimate values using NSUserDefaults.standardUserDefaults.registerDefaults()

    This article describes very well how to “make” them Optional http://radex.io/swift/nsuserdefaults/

    extension NSUserDefaults {
        class Proxy {
            var object: NSObject? {
                return defaults.objectForKey(key) as? NSObject
            }
    
            var number: NSNumber? {
                return object as? NSNumber
            }
    
            var int: Int? {
                return number?.integerValue
            }
    
            var bool: Bool? {
                return number?.boolValue
            }
        }
    }
    

    Use this code

    let userDefaults = NSUserDefaults.standardUserDefaults()
    if var value : Int = userDefaults.objectForKey(key) {
        print(value)
    }