Cocoa Programming for Mac OS X - Aaron Hillegass [58]
To add saving capabilities to your application, edit the method dataOfType:error: in RMDocument.m so that it looks like this:
- (NSData *)dataOfType:(NSString *)aType
error:(NSError **)outError
{
// End editing
[[tableView window] endEditingFor:nil];
// Create an NSData object from the employees array
return [NSKeyedArchiver archivedDataWithRootObject:employees];
}
Note that we just ignored the error argument. There will be no errors.
Loading and NSKeyedUnarchiver
Now you will add the ability to load files to your application. Once again, NSDocument has taken care of most of the details for you.
To do the unarchiving, you will use NSKeyedUnarchiver, which has the following handy method:
+ (id)unarchiveObjectWithData:(NSData *)data
In RMDocument.m, edit your readFromData:ofType:error: method to look like this:
- (BOOL)readFromData:(NSData *)data
ofType:(NSString *)typeName
error:(NSError **)outError
{
NSLog(@"About to read data of type %@", typeName);
NSMutableArray *newArray = nil;
@try {
newArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
@catch (NSException *e) {
NSLog(@"exception = %@", e);
if (outError) {
NSDictionary *d = [NSDictionary
dictionaryWithObject:@"The data is corrupted."
forKey:NSLocalizedFailureReasonErrorKey];
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain
code:unimpErr
userInfo:d];
}
return NO;
}
[self setEmployees:newArray];
return YES;
}
You could update the user interface after the XIB file is loaded, but NSArrayController will handle it for you: the windowControllerDidLoadNib: method doesn’t need to do anything. Leave it here for now because you will add to it in Chapter 13:
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
}
Note that your document is asked which XIB file to load when a document is opened or created. This method also needs no changing:
- (NSString *)windowNibName
{
return @"RMDocument";
}
The window is automatically marked as edited when you make an edit, because you have properly enabled the undo mechanism. When you register your changes with the undo manager for this document, it will automatically mark the document as edited.
At this point, your application can read and write to files. Compile your application and try it out. Everything should work correctly, but all your files will show up as Document Type files and have a generic document icon. Let’s look at how to define our application’s document type more fully.
Setting the Extension and Icon for the File Type
RaiseMan files already have the extension .rsmn, which we configured when we created the project. But .rsmn files need an icon. Find an .icns file and copy it into your project. A fine icon is found at /Developer/Examples/TextEdit/txt. icns. Drag it from the Finder into the Supporting Files group inside the Project Navigator view of Xcode (Figure 10.3).
Figure 10.3. Drag Icon into Project
Xcode will bring up a sheet. Make sure that you check Copy items into destination group’s folder (Figure 10.4). This will copy the icon file into your project directory.
Figure 10.4. Make a Copy
To set the document type information, select the RaiseMan target in the Project Navigator. Under the Info tab, find the Document Types heading and expand the existing document type. Set the name to be RaiseMan Doc, the Icon to txt, and the identifier to com.bignerdranch.raisemandoc.
Next, configure an exported UTI for RaiseMan documents. A UTI describes the type of data contained in the file; we will cover UTIs in more detail later in this chapter.
Exported UTIs are found immediately below the Document Types heading in the target info. If there is not already a blank exported UTI, add one by using the Add button. Set the Description,