Linux guy needs plist/defaults primer

I'm working on application that runs on OSX but does not use the Apple development tools. I need to search for a given plist file (I know the path/filename) and retrieve values for a given app_id and key or keys. That part is straight forward. No problems.


However, the specification that I'm working under requires that if certain attribute in the query definition "is set to 'true', the plist does not have any keys associated with it (i.e. it is not a CFDictionary) and the default value of the plist will be collected."


So, there are apparently situations where a plist may contains no keys. In that case, I need to determine the 'default value'. The quoted portions are taken straight from the spec governing the development of this application.


How do I determine the 'default value' for a plist that has no keys?

Wouldn't a value be associated with a key of some sort?


Thanks

Replies

Hello Henry0Hornet,

It isn't quite as straightforward as that.


There is a defaults system where each set of defaults is identified by a domain. In Objective-C, you would access it via NSUserDefaults. In C, the equivalent is CFPreferencesXXX. This system is managed at runtime via the cfprefsd process. Preferences in a domain may or may not be saved to plist files for persistence. Plist files are strictly for persistence. The only way to access or set preference values is via the API.


You can use the "defaults" command to stuff values into a persistence file. Buf it you do that, you have to make sure to kill the cfprefsd process in order to load the updated values. In some cases, you can hack around on plist files and it seems to work. Don't count on that.


Plist files can be in a few different formats. BBEdit is handy for reading them because it understands the binary format.


As for your situation where a plist may contain no keys, it may be talking about the app's interface to the defaults system. When you initialize NSUserDefaults, you can register some default values. These defaults will be available even if no plist file exists or the key in question does not exist. Only if a value is changed will the plist file get updated. Even then, that updating is controlled by cfprefsd, not the app. Here is an example:

    [[NSUserDefaults standardUserDefaults]
      registerDefaults:
        @{
          kTermsOfUseAccepted: @NO,
          kWelcomeShown: @NO,
          kTrialModeShown: @NO,
        }];


Those "k" values are just string constants. I could do something like:

BOOL welcomeShown = [[NSUserDefaults standardUserDefaults] boolForKey: kWelcomeShown];


to determine if I need to show a welcome dialog. Since I haven't set any value, the result will be false. Later, I could set a value of true. And then I can set it back to false. But once I set a value, the plist (eventually) gets updated. Then I (or rather cfprefsd) wouldn't use the defaults anymore.