Objective-C Programming_ The Big Nerd Ranch Guide - Aaron Hillegass [68]
Edit BNRDocument.m
Now that you’ve got the user interface of your application created, configured, and connected, it’s time to get back to writing code. Click on BNRDocument.m in the project navigator to reopen it in the editor, and implement createNewItem:.
#import "BNRDocument.h"
@implementation BNRDocument
#pragma mark - NSDocument Overrides
- (NSString *)windowNibName
{
return @"BNRDocument";
}
#pragma mark - Actions
- (IBAction)createNewItem:(id)sender
{
// If there's no array yet, go ahead and create one to store our new task
if (!todoItems) {
todoItems = [NSMutableArray array];
}
[todoItems addObject:@"New Item"];
// -reloadData tells the table view to refresh and ask its dataSource
// (which happens to be this BNRDocument object in this case)
// for new data to display
[itemTableView reloadData];
// -updateChangeCount: tells the application whether or not the document
// has unsaved changes. NSChangeDone flags the document as unsaved.
[self updateChangeCount:NSChangeDone];
}
Now implement the required table view data source methods (as defined by the NSTableViewDataSource protocol):
#pragma mark Data Source Methods
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tv
{
// This table view is meant to display the todoItems,
// so the number of entries in the table view will be the same
// as the number of objects in the array.
return [todoItems count];
}
- (id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row
{
// Return the item from todoItems that corresponds to the cell
// that the table view wants to display
return [todoItems objectAtIndex:row];
}
- (void)tableView:(NSTableView *)tableView
setObjectValue:(id)object
forTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row
{
// When the user changes a to-do item on the table view,
// update the todoItems array
[todoItems replaceObjectAtIndex:row withObject:object];
// And then flag the document as having unsaved changes.
[self updateChangeCount:NSChangeDone];
}
Build and run the program. TahDoodle will appear on the screen, and you can add and change to-do items. The big missing feature, however, is the ability to save and reopen a to-do list. To make this happen, you need to override the following methods inherited from BNRDocument’s superclass, NSDocument:
- (NSData *)dataOfType:(NSString *)typeName
error:(NSError **)outError
{
// This method is called when our document is being saved
// We are expected to hand the caller an NSData object wrapping our data
// so that it can be written to disk
// If there's no array, we'll write out an empty array for now
if (!todoItems) {
todoItems = [NSMutableArray array];
}
// Pack our todoItems array into an NSData object
NSData *data = [NSPropertyListSerialization
dataWithPropertyList:todoItems
format:NSPropertyListXMLFormat_v1_0
options:NSPropertyListMutableContainers
error:outError];
// return our newly-packed NSData object
return data;
}
- (BOOL)readFromData:(NSData *)data
ofType:(NSString *)typeName
error:(NSError **)outError
{
// This method is called when a document is being loaded
// We are handed an NSData object and expected to pull our data out of it
// Extract our todoItems
todoItems = [NSPropertyListSerialization propertyListWithData:data
options:0
format:NULL
error:outError];
// return success or failure depending on success of the above call
return (todoItems != nil);
}
Notice that for the first time, you’re implementing a method that takes in an NSError**. In this case, we