UserDefaults
UserDefaults is essentially a very tiny light weight database that persists between launchings of the app. It's great for things like "settings" and such, not for anything big.
We are limited in what we can store in UserDefaults, it only stores Property List data.
A Property List is any combo of Array
, Dictionary
, String
, Date
, Data
or a number (Int
, etc). This is an old objective-c api with no type that represents all those, so the api uses Any
. If this were a new, swift-like api, it would almost certainly not use Any
(likely there would be a protocol or some such that those types would implement.)
It's "core" functionality is simple. It just stores an retrieves Property List by key...
func set(Any?, forKey: String)
func object(forKey: String) -> Any? // optional because it might not be found
It say Any
but it's not really Any
it must be one of the types mentioned above, and when it returns a property it is guaranteed to be a Property List.
Reading And Writing
We don't usually create one of these databases with UserDefaults(). Instead, we use the static (type) var called standard.
let defaults = UserDefaults.standard
Setting a value in the database is done with set
. You can pass anything as the first argument as long as it's a combo of the Property List types.
defaults.set(3.1415, forKey: "pi")
defaults.set([1,2,3], forKey: "My Array")
defaults.set(nil, forKey: "Some Setting") // removes any data at that key
Getting defaults outs with UserDefaults has come convenience methods so that we don't get a value of type Any?
but rather they type we are looking for, but when we do get type Any
of course it will be a Property List type.
func double(forKey: String) -> Double
func array(forKey: String) -> [Any]? // retunrns nil if non-Array at that key
func dictionary(forKey: String) -> [String: Any]? // note that keys in return are Strings
Saving
Our changes will occasionally be auto saved, but we can force them to be saved at any time with synchronize
. It's not computationally "free" to synchronize, but it's not that expansive either.
if !defaults.synchronize() {
// failed! but not clear what you can do about it
}