The defaults system is the easiest persistence solution on iOS, tvOS, macOS, iPadOS, and watchOS. A defaults database is nothing more than a key-value store. You interact with the defaults system through the UserDefaults
class. Let's take a look at the API of the UserDefaults
class.
Shared Defaults Object
Most applications interact with the shared defaults object. You access the shared defaults object through the standard
class property.
import Foundation
// Access Shared Defaults Object
let userDefaults = UserDefaults.standard
The user's default database is written to disk as a property list or plist. A property list or plist is an XML file. The UserDefaults
class keeps the contents of the property list in memory while your application is running to improve performance. It loads the property list once and writes any changes you make to disk.
Reading or Getting Values From User Defaults
The API of the UserDefaults
class is easy to use in Swift. The most basic API to read or get values from the user's defaults database in Swift is object(forKey:)
. This method returns a value of type Any?
, an optional. As I mentioned earlier, the defaults database is a key-value store. The UserDefaults
class looks up the value for the key that is passed to the object(forKey:)
method and returns a value if a value exists for the given key. It returns nil
if no value exists for the given key.
import Foundation
// Access Shared Defaults Object
let userDefaults = UserDefaults.standard
// Read/Get Value
userDefaults.object(forKey: "myKey")
The UserDefaults
class also defines a number of convenience methods for retrieving values of a specific type. To access the boolean value for a given key, you invoke bool(forKey:)
. If no key-value pair can be found for the given key, bool(forKey:)
returns false
.
import Foundation
// Access Shared Defaults Object
let userDefaults = UserDefaults.standard
// Read Boolean
let value = userDefaults.bool(forKey: "myKey")
Know that bool(forKey:)
is a convenience method. The following expression has the same result, but it is less elegant and more verbose.
import Foundation
// Access Shared Defaults Object
let userDefaults = UserDefaults.standard
// Read Boolean
let value = userDefaults.object(forKey: "myKey") as? Bool ?? false
Writing or Setting Values To User Defaults
Creating or updating a key-value pair is trivial. You simply invoke the set(_:forKey:)
method on the UserDefaults
instance. In this example, we set the value of myKey
to true
by invoking the set(_:forKey:)
method on the shared defaults object.
import Foundation
// Access Shared Defaults Object
let userDefaults = UserDefaults.standard
// Write/Set Value
userDefaults.set(true, forKey: "myKey")
Data Types
It is essential that you know which data types can be stored in the defaults database. You can only store a predefined list of data types, that is, strings, numbers, Date
objects, and Data
objects. You can also store arrays or dictionaries of these types. In this example, we define a struct with name User
and create a User
object with name Bart
. We then pass the User
object to set(_:forKey:)
method of the UserDefaults
class.
import Foundation
struct User {
let name: String
}
// Create User
let user = User(name: "Bart")
// Write User to User's Defaults
UserDefaults.standard.set(user, forKey: "user")
This won't work. If you run this example in a playground, a runtime exception is thrown. Why is that? The user
constant is of type User
. Remember that only strings, numbers, Date
objects, and Data
objects can be stored in the user's defaults database.
You can store custom objects in the defaults database with a workaround, though. I explain that in this post.
When to Use User Defaults?
The defaults system is a good fit if you need to store small amounts of data that don't need to be secured. For sensitive information, such as a username or an access token, I strongly recommend using the keychain. Even though you can store any type of data as binary data in the user's defaults database, this approach isn't recommended if you need to store large amounts of data.