Monday, July 8, 2019

Introduction to User's Defaults Database

To store user's preferences in an app, we can use the user's defaults database, which will be created by the system on each device (iOS or Mac OS) by the time we access it. Note that the database is not suitable for large data and heavy transactions. Preferences are grouped into domains. There are 5 different types of domains:
1). The argument domains (UserDefaults.argumentDomain): Volatile
2). Application (identified by the app's identifier, for example, com.vathanakmao.MyCalculator): Persistent, should be used by their corresponding apps.
3). The global domains (UserDefaults.globalDomain): Persistent, used by system frameworks and accessed by different apps.
4). The languages domains: Volatile
5). The registration domain (UserDefaults.registrationDomain): Volatile

The lifetime of a preference depends on the domain, in which it is stored in. Some domains store preferences persistently, which means that the preferences continue to exist across app launches. Some others store preferences in more volatile way (shorter life), keeping preference values only for the life of the corresponding user defaults object (the user defaults object may be destroyed by the system or when the app exits).

For example, calling UserDefaults.standard.register(default: [String, Any]) method stores the preference dictionary object in the registration domain, and the object is deleted when the app exits. We can test it while in development by adding the code in the AppDelegate class and run the project in the simulator from Xcode. After that, quit the simulator and remove the code from the AppDelegate then run the project again. In contrast, calling the UserDefaults.standard.set(_,forKey)method stores the preference object persistently, which means that the object can still be accessed in the next sub sequent project launches even if after the method call is removed.

Storing value


UserDefaults.standard.set(1000, forKey: "item1")
    

It's recommended that the value should be as simple as possible for better performance even though the Data type is supported. The value of a primitive type would be ideal.

Getting value


UserDefaults.standard.integer(forKey: "item1")
    

If the object does not exist, the returned value falls back to the default value of its corresponding type. It would be 0 (zero) in the case above (, and false in case it's Bool)

The system searches for the key in all domains one by one based on their orders listed above until the key is found.

Registering default value for certain key


For example, calling UserDefaults.standard.integer(forKey) method on non-existent key would return 0 (zero), but 0 is meaningful in our case and we want it to return a different number like -1 (minus one). We should register the default value for that key in AppDelegate class as following:
    
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
 let preferences = ["item1", -1]
 UserDefaults.standard.register(defaults: preferences)
}
    



References
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/UserDefaults/AboutPreferenceDomains/AboutPreferenceDomains.html#//apple_ref/doc/uid/10000059i-CH2-SW6

No comments:

Post a Comment