Re: CFPreferences vs. NSUserDefaults
Re: CFPreferences vs. NSUserDefaults
- Subject: Re: CFPreferences vs. NSUserDefaults
- From: Chris Parker <email@hidden>
- Date: Tue, 26 Mar 2002 15:13:14 -0800
Hi Evan,
On Tuesday, March 26, 2002, at 11:36 AM, Evan Coyne Maloney wrote:
[some text deleted]
All of this experiementation led me to the following questions. Any
help/advice/flames would be welcome!
1. What do the CFPreferences calls expect the "appName" parameter to
be? "appName" implies name (as in "Dock" or "Finder"), but the
documentation says "the ID of the application", which implies bundle
identifier (as in "com.apple.dock" or "com.apple.finder").
Applications aren't necessarily restricted to bundle IDs. Non-bundled
applications using the CFPreferences API wind up having their
application name chosen as the identifier if they use
kCFPreferencesCurrentApplication as the appName parameter. If you wish
to synchronize against a specific domain, you have to discover that
domain somehow.
2. Is NSUserDefaults built on top of CFPreferences? I would assume so,
but if that's the case, then why can't I retrieve the keys for the
Dock's preferences using CFPreferences? It seems that I can only
interact with the Dock's preferences though NSUserDefaults. For
example, both of the following calls return nil:
CFPreferencesCopyKeyList((CFStringRef) @"com.apple.dock",
kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
This is returning nil probably because the Dock doesn't store a ByHost
preference domain. This is asking for a specific domain triplet (in
terms of {app, user, host}): {com.apple.dock, this user, this host}
which would be the plist stored in
~/Library/Preferences/ByHost/com.apple.dock.<ethernet address>.plist.
If that plist isn't there, there's nothing to get.
What you probably are looking for is
CFPreferencesCopyKeyList((CFStringRef)@"com.apple.dock",
kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
which is in ~/Library/Preferences/com.apple.dock.plist
CFPreferencesCopyKeyList((CFStringRef) @"Dock",
kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
Again, this is looking for something similar: {Dock.<ethernet
address>.plist, this user, this host} which is most likely non-existant.
3. Do the CFPreferences calls simply not work for Cocoa apps? Is the
Dock a Carbon app or Cocoa app? (I'd assume Cocoa, since the Dock
wasn't ported from OS 9.)
They work fine in Cocoa apps, and in fact some features available to
CFPreferences (like by-host preferences) are only available through the
CF API (this is being worked on).
[4. is slightly edited by me]
4. Can NSUserDefaults' synchronize method be used to interact with
other apps? Can the equivalent CFPreferences calls?
Yes.
Even while running?
Sure, but see my notes at the bottom of this email.
Or does synchronization only work with the app the calls it? If the
latter, then WHY does CFPreferences allow me to specify the application?
You're specifying the domain you want =your= application to synchronize
against. You're not really specifying the application who owns those
preferences.
5. Lastly, what does preference synchronization do, precisely? The
documentation implies that it can be used to (1) reload the ".plist"
file from disk AND (2) write the preferences BACK to the ".plist" file.
What happens if there's a conflict? The app's preferences change
internally AND the file changes THEN a synchronize is performed. What
happens? Who gets priority? Is there a merge, a la CVS? Or does
everything get hosed?
There -is- a lightweight merge, but any values for keys that the
application has made itself will win out over anything you may have set
in the file.
NOTE:
The warning that was referenced earlier by Jonathan Feinberg from the
defaults(1) man page can basically be restated as follows:
The application itself is the final arbiter of its preferences. Changes
made to preferences from outside the application's context cannot be
expected to persist since the application itself decides to sync what
it's got out to disk.
I can't jump up and down about this enough. If the application itself
wants to provide a mechanism for preferences to be modified externally
in a consistent manner, the application will have to provide that
through some form of interprocess communication - whether that's a
distributed notification, or an Apple Event, or something else.
Applications can agree on using a specific (external) domain (i.e. suite
preferences) but should agree amongst themselves how to handle access to
that domain.
It is expected that applications may wish to read values for keys in
other preference domains, but the application owning that domain is the
definitive source for when that domain is synchronized, etc.
.chris
--
Chris Parker <email@hidden>
Cocoa Frameworks Engineer
Apple Computer, Inc.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.