In this tutorial I will teach you how to use NSUserDefaults in Swift. I will go over a few of the Caveats and information needed when using NSUserDefaults including how to save data and also how to read that data.
What is NSUserDefaults?
Basically, NSUserDefaults is a class that provides simple storage of different data types solution. It is perfect for those small bits of information you will need to persist between app launches or device restarts. You can use NSUserDefaults to store any basic data type as long as the app is installed. Not only can you can use it to store basic types such as Bool, Float, Double, Int, String, or NSURL, but you can also store a few more complex types like arrays, dictionaries, NSDate & NSData values.
Just to let you know, This tutorial will only be covering NSUserDefaults in swift. There is an NSUserDefaults Objective-C version if that is what you are looking for.
Storing data to NSUserDefaults
The first thing we need to do when starting with Swift NSUserDefaults is to make sure that we make a reference. We do this by initiating a new instance of a class and assigning it to a variable. Like so:
let defaults = NSUserDefaults.standardUserDefaults()
Now, we can add values into our class rather easily. So, lets say that the default age of an app user us 25. We can add that to the class using forKey in setInteger() and making sure we prefix it with the name of the class. Like so:
defaults.setInteger(25, forKey: "Age")
This has now created a object in the defaults class with the value of 25. In Swift there are several options for storing data into NSUserDefaults:
- func setInteger(value: Int, forKey defaultName: String)
- func setURL(url: NSURL, forKey defaultName: String)
- func setDouble(value: Double, forKey defaultName: String)
- func setBool(value: Bool, forKey defaultName: String)
- func setObject(value: AnyObject?, forKey defaultName: String)
- func setFloat(value: Float, forKey defaultName: String)
As you might remember, I mentioned earlier that you can also save more complex pieces of data to NSUserDefaults like Arrays and Dictionaries. When you set NSArray and NSDictionary objects, their contents must be property list objects. Check out the Apple documentation on: Introduction to Property Lists
So.. to save an Array to NSUserDefaults, you would use setObject() like so:
defaults.setObject("iOS-Blog", forKey: "Name") defaults.setObject(NSDate(), forKey: "Date")
and similarly for Dictionaries you would write it like this:
let dict = ["Name": "iOS-Blog", "tagline": "Awesome Tutorials", "rating": "10/10"] defaults.setObject(dict, forKey: "SavedDict")
Note that in Swift, strings, arrays and dictionaries are all classed as structs, not objects. But NSUserDefaults was written for NSString and friends – all of whom are 100% interchangeable with their Swift equivalents.
Swift Read NSUserDefaults
Now you need to be a little more careful and strict when reading data from NSUserDefaults and to make sure you check the return type carefully to ensure you know what you’re getting. The methods that can be used are:
- func integerForKey(defaultName: String) -> Int
- func boolForKey(defaultName: String) -> Bool
- func doubleForKey(defaultName: String) -> Double
- func floatForKey(defaultName: String) -> Float
- func stringForKey(defaultName: String) -> String?
- func URLForKey(defaultName: String) -> NSURL?
- func dataForKey(defaultName: String) -> NSData?
- func objectForKey(defaultName: String) -> AnyObject?
- func stringArrayForKey(defaultName: String) -> [AnyObject]?
- func arrayForKey(defaultName: String) -> [AnyObject]?
- func dictionaryForKey(defaultName: String) -> [NSObject : AnyObject]?
So, why is Knowing the return values important? Well, lets say you use boolForKey() and get back false for the result. Does that mean the key didn’t exist, or did it perhaps exist and you just set it to be false? See the dilemma?
Just to give you a heads up, objectForKey() will give you the most trouble because the result you get will be an optional object. Your options when using objectForKey() are either to Use as to typecast your object to the data type it should be. Use as! to force typecast your object to the data type it should be or use as? to optionally typecast your object to the type it should be. Note: the first two options are available from Xcode 6.3 or later.
So, if you use as/as! and your objectForKey() returned the result: nil, your application will crash. You should only use these if you are absolutely certain what the return will be..
The solution here is to use the nil coalescing operator which is written like: ??. This does two things at once: if the object on the left is optional and exists, it gets unwrapped into a non-optional value; if it does not exist, it uses the value on the right instead. This means we can use objectForKey() and as? to get an optional object, then use ?? to either unwrap the object or set a default value, all in one line.
Remember the Array we created earlier? Here is how we will get that Array using the nil coalescing operator:
let array_get = defaults.objectForKey("SavedArray") as? [String] ?? [String]()
if the object SavedArray exists in the NSUserDefaults and is a string array it will be placed into the array_get constant as defined above using let array_get. If it doesn’t exist (or if it does exist and isn’t a string array), then let array_get gets set to be a new string array. To use this on the Dictionary that we set earlier, the code would be:
let dict = defaults.objectForKey("SavedDict") as? [String: String] ?? [String: String]()
IF you need to remove the value from a set object in NSUserDefaults, then you would use the removeObjectForKey method:
That’s all folks, I hoped it helped. Feel free to comment below if you need help. Also please help me share this article and give it a like and/or share.
To summarize, in this swift tutorial I have shown you how to add data to NSUserDefaults using the methods; setObject, setInteger, setURL, setDouble, setBool, setObject and setFloat. And then how to read the data stored in NSUserDefaults as well as removing the data using: removeObjectForKey