UserDefaults in Swift


A small set of data is required to be stored and accessed very frequently and need to be persisted across sessions or app launches. One way of keeping them is using a local database like core data in an iOS app. But core data is helpful in the case of tables and queries. There is another way to store a small set of data, UserDefaults.

Let's try to understand what are UserDefaults first.

What is UserDefaults

UserDefault is used to store small pieces of data which can persist across sessions or app launches. Things like auth token, username, emailid, display name which are being used accross the sessions can be store in UserDefaults.

How UserDefaults works

UserDefaults stores data in a key-value pair where the key can be of string type and value can be of Int, Float, Double, Bool, String, Data, URL, Array, Dictionary and much more.

The information will be stored in a .plist format on the local disk.

Currently, there is no size limit to store data in UserDefaults but it's usually preferred for the small size of data only.

How to use UserDefaults

In order to use the UserDefaults, first, get the standard UserDefault object.
  
let defaults = UserDefaults.standard
standard is a global instance of NSUserDefaults or which only getter is exposed. We can't set any reference to it.
  
/**
+standardUserDefaults returns a global instance of NSUserDefaults configured to search the current application's search list.
*/
open class var standard: UserDefaults { get }

Write data to UserDefaults

We can set the value for any key using set function on UserDefault.standard object. The set method has multiple overloads that have the same signature but takes different parameters as a value along with a String key.
  
let defaults = UserDefaults.standard

//String Value
defaults.set("Suneet Agrawal", forKey: "stringKey")

//Int Value
defaults.set(1, forKey: "integerKey")

//Double Value
defaults.set(30.0, forKey: "doubleKey")

//Array Value
defaults.set([1,2,3], forKey: "intArrayKey")

Read data from UserDefaults

The syntax for getting the value from UserDefault is a bit different from set. Each has the datatype as a function name which takes a key as a String type parameter for which we want to get the value.

Keep in mind these function returns nil if there is no value existing for the key or is of a different datatype.
  
let defaults = UserDefaults.standard

//String Value
let stringValue = defaults.string(forKey: "stringKey")

//Int Value
let intValue = defaults.integer(forKey: "integerKey")

//Double Value
let doubleValue = defaults.double(forKey: "doubleKey")

//Array Value
let intArrayValue = defaults.string(forKey: "intArrayKey")

Remove data for key

The value for a particular key can be removed using removeObject function. This will set the value as nil.
  
/// -removeObjectForKey: is equivalent to -[... setObject:nil forKey:defaultName]
open func removeObject(forKey defaultName: String)

let defaults = UserDefaults.standard

defaults.removeObject(forKey: "stringKey")

Remove data for all keys

There is no direct function to remove all key-value pairs. The best way to do the same is to iterate over all the keys and remove them one by one.
  
for key in Array(UserDefaults.standard.dictionaryRepresentation().keys) {
UserDefaults.standard.removeObject(forKey: key)
}

Default value for key in UserDefaults

The behavior for the get type is weird if the key is not set.
In that case, if we are trying to get the value for any primitive data type, it will return a default value like 0 for Integer but if we are trying to get an object value, it will return nil.

In order to unify the behavior across the app, we can use object(forKey:) function which returns Any? and we can cast it to the required datatype. We can even provide the default value if it returns nil or the key doesn't exist.
  
let defaultValue = UserDefaults.standard.object(forKey: "intArrayKey") as? [Int]? ?? [Int]()

Things to keep in mind while using UserDefault

  • It stores data in key-value pairs. The key-value pairs are stored in .plist format on the local disk.
  • We can store multiple data types in UserDefault.
  • UserDefault is useful only for a small set of data. It is not a replacement for core data.