PSPreferences

Plain C on CoreFoundation types. Available from anywhere, including a constructor that runs before much else is set up.

Every function is named after the CFPreferences one it replaces, so switching a tweak over is mostly a matter of changing CF to PS. The one difference: the store is shared by every user on the Mac, so where CFPreferences takes a user name and a host name, these take only the domain.

Include
#import "PSPreferences.h"

One key

Signatures
CFPropertyListRef PSPreferencesCopyAppValue(CFStringRef key, CFStringRef domain);
void              PSPreferencesSetAppValue(CFStringRef key, CFPropertyListRef value, CFStringRef domain);
Boolean           PSPreferencesGetAppBooleanValue(CFStringRef key, CFStringRef domain, Boolean *exists);
CFIndex           PSPreferencesGetAppIntegerValue(CFStringRef key, CFStringRef domain, Boolean *exists);

Copy functions follow the CoreFoundation rule: you own the result and must CFRelease it. They return NULL when the key is not set. Passing NULL as the value removes the key.

exists is how the typed getters tell a stored false or 0 apart from nothing stored at all. Pass NULL if you do not need to.

Several keys

Signatures
CFDictionaryRef PSPreferencesCopyMultiple(CFArrayRef keysToFetch, CFStringRef domain);
void            PSPreferencesSetMultiple(CFDictionaryRef keysToSet, CFArrayRef keysToRemove,
                                         CFStringRef domain);
CFArrayRef      PSPreferencesCopyKeyList(CFStringRef domain);

Pass NULL as keysToFetch to get every key in the domain. PSPreferencesSetMultiple sets and removes in one write, so other processes see all of it change at once.

Synchronizing

Signature
Boolean PSPreferencesAppSynchronize(CFStringRef domain);

Writes are saved as soon as they return, so you never need to call this. It exists so a call left over from CFPreferences code does no harm.

Reacting to changes

Every write posts the notification <domain>/prefsChanged, including the ones your settings pane makes. Listen for it to pick up a new value without restarting:

C
static void changed(CFNotificationCenterRef c, void *o, CFNotificationName n,
                    const void *obj, CFDictionaryRef info) {
    reloadSettings();
}

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, changed,
                                CFSTR("com.example.mytweak/prefsChanged"), NULL,
                                CFNotificationSuspensionBehaviorCoalesce);

Example

C
Boolean exists = false;
Boolean enabled = PSPreferencesGetAppBooleanValue(CFSTR("enabled"),
                                                  CFSTR("com.example.mytweak"),
                                                  &exists);
if (!exists) enabled = true;   // your default

CFNumberRef n = PSPreferencesCopyAppValue(CFSTR("intensity"),
                                          CFSTR("com.example.mytweak"));
if (n) { /* use it */ CFRelease(n); }

See also

PSUserDefaults for the same store with typed accessors and registered defaults, which removes the exists dance above.