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 = UserDefaults.standard
let defaultValues = ["key1" : 12, "key2" : 12.6]
defaults.register(defaults: defaultValues)
super.init()
}
Then you can read the values from everywhere always as non-optionals
let defaults = UserDefaults.standard
myVariable1 = defaults.integer(forKey: "key1")
myVariable2 = defaults.double(forKey:"key2")
NSUserDefaults optionals in Swift
You are force unwrapping your optionals, and you should get them as strings before appending them to your array.
A cleaner way to set the defaults would be to coalesce the unwrapping of your optionals, Try the following approach:
func getFiltersSetts() -> [String] {
let userDefs = NSUserDefaults.standardUserDefaults()
var defsArray = [String]()
defsArray.append(userDefs.stringForKey("gender") ?? "Male")
defsArray.append(userDefs.stringForKey("age") ?? "21-30")
defsArray.append(userDefs.stringForKey("online") ?? "Online")
return defsArray
}
The code above uses the coalesce (??) operator. If your optional, say userDefs.stringfForKey("gender"), returns nil, the coalesce operator will use the default value "Male".
Then at a later time you can save your user defaults (or create them) if they haven't been set before.
Also, is worth noticing that you should be unwrapping your optionals using the if let notation. Instead of comparing if its != nil, as this will prevent you from force unwrapping them inside the code block.
I hope this helps!
Swift - NSUserDefaults Having value or not?
Check below possible conditions.
1. Check NSUserDefaults is null:
if(NSUserDefaults.standardUserDefaults().objectForKey("EMP_NAME") == nil)
{
print("NULL")
}
2. Check NSUserDefaults String is null or Empty:
if((NSUserDefaults.standardUserDefaults().stringForKey("EMP_NAME")) == "" || NSUserDefaults.standardUserDefaults().stringForKey("EMP_NAME") == nil)
{
print("NULL or Empty String")
}
Store optional bool in NSUserDefaults
You can just take value from UserDefaults and try to cast it to Bool
. If there is no value for key u get nil.
let myBool = UserDefaults.standard.object(forKey: "BoolKey") as? Bool
or
let myBool = UserDefaults.standard.value(forKey: "BoolKey") as? Bool
myBool = nil
in both cases
thanks user28434
for addition
How to safely unwrap a value from user defaults?
As suggested in doc:
-boolForKey:
is equivalent to-objectForKey:
, except that it converts the returned value to aBOOL
. If the value is anNSNumber
,NO
will be returned if the value is0
,YES
otherwise. If the value is anNSString
, values of"YES"
or"1"
will returnYES
, and values of"NO"
,"0"
, or any other string will returnNO
. If the value is absent or can't be converted to aBOOL
,NO
will be returned.
open func bool(forKey defaultName: String) -> Bool
It is not an optional anymore. So you don't need to cast it with if let
.
You can directly use:
let seen = defaults.bool(forKey: UtilitiesKeys.mainTutorialSeen)
Delete key values for NSUserDefaults in Swift
removeObjectForKey is the right way to go.
This will remove the value for the selected key. The following code sets a string value for a key in NSUserDefaults, prints it and then uses removeObjectForKey to remove and print the key value again. After removeObjectForKey the value is nil.
let prefs = NSUserDefaults.standardUserDefaults()
var keyValue = prefs.stringForKey("TESTKEY")
print("Key Value not set \(keyValue)")
let strHello = "HELLO WORLD"
prefs.setObject(strHello, forKey: "TESTKEY")
keyValue = prefs.stringForKey("TESTKEY")
print("Key Value \(keyValue)")
prefs.removeObjectForKey("TESTKEY")
keyValue = prefs.stringForKey("TESTKEY")
print("Key Value after remove \(keyValue)")
Returns:
Key Value not set nil
Key Value Optional("HELLO WORLD")
Key Value after remove nil
Update Swift 3:
let prefs = UserDefaults.standard
keyValue = prefs.string(forKey:"TESTKEY")
prefs.removeObject(forKey:"TESTKEY")
Unable to print without Optional()
So, rather than checking whether something is nil
, and then when you find out it's not, you both force unwrap and force cast it, we can instead pull this value out safely using optional binding and the correct NSUserDefaults
method: stringForKey(_:)
:
if let data = NSUserDefaults.standardUserDefaults().stringForKey("newString") {
print(data)
}
But, your second & third tries shouldn't be showing the string as optional. This playground demonstrates effectively the exact same thing as what you're doing here with NSUserDefaults
.
func optionalFunc() -> Any? {
return "Hello world."
}
print(optionalFunc())
/* unsafe */ print(optionalFunc() as! String!) /* unsafe */
/* unsafe */ print(optionalFunc() as! String) /* unsafe */
/* unsafe */ print(optionalFunc()!) /* unsafe */
if let unwrapped = optionalFunc() as? String {
print(unwrapped)
}
As you can see, only the first case prints the Optional("Hello world.")
string.
Swift NSUserDefaults first time nil
stringForKey
returns nil
when there has not been a value saved already.
You need to give your values a default. The easiest way to do this is with the ??
operator, that replaces nil
with another value:
let State = save.stringForKey("StateSave") ?? "-"
Some general advice: you need to stop using !
so much. Usually when something returns nil
, it’s for a good reason – it might be nil
. When you unwrap it with !
, your program will crash (with not much helpful info as to why). Similarly, it’s usually a bad sign if you’re comparing values to nil
.
Instead, take a look at this list of optional handling techniques for some alternatives.
If let clause when getting from NSUserDefaults()
Your primary approach is fine.
boolForKey
of NSUserDefaults
doesn't return an optional therefore any optional binding attempt is meaningless.
func boolForKey(_ aKey: String) -> Bool
If a Boolean value is associated with the specified key, that value is
returned. If the key was not found, this method returns NO.
Related Topics
Spritekit Not Respecting Zposition
How to Use Pod in Notification Service Extension
Nstextattachment Image Not Shown in Nstextview (But in Uitextview)
Uitableview Has Unwanted Animation When Reloaddata Is Called
Scenekit Flattenedclone - Incorrect Use of Objc_Storeweak() and Objc_Loadweak() Error
Uilabel Word Wrap Feature Leaving Space Even When Sufficient Space Available for The Word
Uipageviewcontroller Setviewcontrollers, UIpagecontrol Not Showing Right Current Number
Get Apple Watch Heartratevariabilitysdnn Realtime
How to Show Viewcontroller from a Non-Viewcontroller Helper Class
Cancel All Operations + Afnetworking 3.0
How to Compile Aws Customidentityprovider on Xcode 8 Beta 6
Native-Like Momentum-Scrolling on Body in iOS Webapp
iOS Google Maps Sdk Gmsmarker Positioning
Duplicate Collectionview Cells After Reloaddata with Firebase Query
Passing Data Between View Controllers: from UItableview to a Details View Controller