Tuesday, September 29, 2009

Cocoa: More about archiving

This post is the result from some more tests I've run on archiving. Some interesting points:

• I'm compiling and running the tests from the command line. I've enabled garbage collection as you can see in the compiler invocation on the first line of the listing.

• The object to be archived is an instance of NSColor. In order to use this class, I need to not only import the AppKit but also link against it. I missed that at first.

• Just for fun, I get a color from the "Crayons" color list.

• The last example used NSKeyedArchiver, but since we're not using a key, we can just use NSArchiver.

• The interesting part is where the action happens in:

[archiver encodeObject:maroon];


Essentially, the archiver says to the object: encode yourself! Since NSColor conforms to NSCoding, it should (and fortunately, is) able to do that.



• The encoded color is an NSMutableData object, and can now be added to an array and written to a plist file.



Output:


2009-09-29 16:13:04.573 test[1077:10b] color NSCalibratedRGBColorSpace 0.501961 0 0.25098 1
2009-09-29 16:13:04.576 test[1077:10b] data <040b7374 7265616d 74797065 6481e803 84014084 8484074e 53436f6c 6f720084 84084e53 4f626a65 63740085 84016301 84046666 66668381 80003f00 83818080 3e0186>
2009-09-29 16:13:04.582 test[1077:10b] array1 (
<040b7374 7265616d 74797065 6481e803 84014084 8484074e 53436f6c 6f720084 84084e53 4f626a65 63740085 84016301 84046666 66668381 80003f00 83818080 3e0186>
)
2009-09-29 16:13:04.582 test[1077:10b] filename /Users/te/Desktop/a.plist
2009-09-29 16:13:04.585 test[1077:10b] color NSCalibratedRGBColorSpace 0.501961 0 0.25098 1


Code listing:


// gcc -o test test2.m -framework Foundation -framework AppKit -fobjc-gc-only
// ./test
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>

int main (int argc, const char * argv[]) {
NSColor *maroon;
NSColorList *CL;
CL = [NSColorList colorListNamed:@"Crayons"];
maroon = [CL colorWithKey:@"Maroon"];
NSLog(@"color %@", maroon);

NSMutableData *mdata;
mdata = [[NSMutableData alloc] initWithCapacity:100];
NSArchiver *archiver;
archiver = [[NSArchiver alloc]
initForWritingWithMutableData:mdata];
[archiver encodeObject:maroon];
NSLog(@"data %@", [mdata description]);

NSArray *arr;
arr = [NSArray arrayWithObject:mdata];
NSLog(@"array1 %@", arr);

NSString *fn;
bool result;
fn = NSHomeDirectory();
fn = [fn stringByAppendingString:
@"/Desktop/a.plist"];
NSLog(@"filename %@", fn);
[arr writeToFile:fn atomically:YES];

NSArray *arr2;
arr2 = [NSArray arrayWithContentsOfFile:fn];
NSColor *color;
NSData *data = [arr2 objectAtIndex:0];
color = [NSUnarchiver unarchiveObjectWithData:data];
NSLog(@"color %@", color);
return 0;
}