Document Level Parameters Using Core Data: A Guide for Cocoa Developers
Apple has already designed a way for your application to store its application-level parameters. This API guarantees that they will be stored in a consistent place in the user’s home directory and makes it very easy for you to read, write, and monitor these values. But there is another situation that is not covered by these application-level defaults/parameters. In some situations it is useful for the application to store parameters at the document level rather than at the application level.
One solution to this problem is to have a "singleton" like object in the Core Data model that has a single row in a table, and that row grows as more parameters are added to the application. Although this solution is not a very clean one, it is quite common in applications that have a database store as their back end. Another solution is to have a parameters table, which stores name/value pairs, and each parameter is a row in the database table. Although this solution is more suited to the database back end, it requires the application to perform fetches against the store for each parameter. If these fetches are not handled in a centralized location, the database code gets strewn throughout the application. In addition, this solution does not lend itself to Cocoa Bindings very well.
The solution I have come up with and utilize in my applications is a bit of a mix of the above. Utilizing Objective-C’s Key-Value Coding API, I can access my document-level parameters in a name/value table without having to create a large number of fetch requests throughout the application. Following are the details to this solution.
In a normal application, key value coding allows you to access either variables that do not have accessor methods or to access those accessor methods directly. One of the benefits of KVC is that you do not have to worry about which of cases is present in the object you are accessing, it "just works." In the event that you request a value from an object that the object does not normally handle, you do not just get an error; instead you get one last chance to respond to the request cleanly before an error is thrown. When you request a value that the object does not support, valueForUndefinedKey: is called. Similarly, if you attempt to set a value that the object does not support, setValue:forUndefinedKey: is called. By overriding these two methods in our NSDocument, it is possible to request values on the document that will be translated into requests for parameters in the persistent store.