For the More Curious: NSUserDefaultsController


#1

I’d like to write code that uses the most modern techniques and so I’m wondering if bindings should indeed be used instead of target/action.

If I use bindings, as discussed on p. 207, it appears I need to do more than what is shown in Figure 13.6. I’ve tried to comment out code that was added in this chapter but have been unable to arrive at the correct code to include after setting the binding as shown in the figure.


#2

Paul,

I was able to get this working. Here is my solution:

PreferenceController.h:

#import <Cocoa/Cocoa.h>

extern NSString * const BNRTableBgColorKey;
extern NSString * const BNREmptyDocKey;

@interface PreferenceController : NSWindowController {
	IBOutlet NSColorWell *colorWell;
	IBOutlet NSButton *checkBox;
}

-(IBAction)resetDefaults:(id)sender;
@end

PreferenceController.m:

#import "PreferenceController.h"

NSString * const BNRTableBgColorKey = @"TableBackgroundColor";
NSString * const BNREmptyDocKey = @"EmptyDocumentFlag";

@implementation PreferenceController
- (id)init
{
	if (![super initWithWindowNibName:@"Preferences"])
		return nil;
	return self;
}

-(IBAction)resetDefaults:(id)sender
{
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	[defaults removeObjectForKey: BNRTableBgColorKey];
	[defaults removeObjectForKey: BNREmptyDocKey];
}
@end

And finally, change the windowControllerDidLoadNib: in MyDocument.m to the following:

- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
    [super windowControllerDidLoadNib:aController];

//The following is needed to hook up the NSTableView to the preferences, since it does
//not expose the backgroundColor binding in IB:
	NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
    [bindingOptions setObject:NSKeyedUnarchiveFromDataTransformerName forKey:@"NSValueTransformerName"];

    [tableView bind: @"backgroundColor"
		   toObject: [NSUserDefaultsController sharedUserDefaultsController]
        withKeyPath:@"values.TableBackgroundColor"
			options:bindingOptions];
}

Aside from the above changes, you will need to hook up the rest in Interface Builder. A good tutorial for doing so is on Apple’s website

I hope this helps. Good luck!

David