With this design, we can access our parameters within each document without having to worry about the underlying structure. We also don’t need to stop coding just to hop over and add a parameter to the object. We can work with DocumentPreferences in the same manner that we work with NSUserDefaults.
This same design can be used in a nondocument application by changing the DocumentPreferences object by directly adding the methods ‑valueForUndefinedKey: and ‑setValue:forUndefinedKey: to the NSApplicationDelegate along with the NSManagedObjectContext.
Whether or not we’re working in a document model, we can now access persistent store--specific parameters with a single call similar to the following:
| NSString *value = [[self preferences] valueForKey:@"exampleKey1"]; |
We can also set them with a call similar to the following:
| [[self preferences] setValue:@"someValue" forKey:@"someKey"]; |
In both of these examples, we’re calling ‑valueForKey: and ‑setValue:forKey: directly on the DocumentPreferences object and not worrying about whether the value exists. If it doesn’t exist, we’ll receive a nil. If it has been set as a default, we get the default back, and if we’ve overridden the default or previously set the property, it’s returned.
Lastly, like the NSUserDefaults, the default values aren’t persisted to disk. Therefore, we need to set them every time we initialize the DocumentPreferences.
| NSMutableDictionary *defaults = [NSMutableDictionary dictionary]; |
| [defaults setValue:[NSNumber numberWithBool:YES] forKey:@"default1"]; |
| [defaults setValue:@"DefaultValue2" forKey:@"default2"]; |
| [defaults setValue:@"DefaultValue3" forKey:@"default3"]; |
| [[self preferences] setDefaults:defaults]; |
However, we don’t need to worry about changing the defaults at a later date. If we change the defaults in a subsequent version, they’ll automatically be updated if the user hasn’t overridden them.