Sunday, October 11, 2009

Bright and shiny icons

I spent most of a day trying to get an application to tell the Finder "yes I will read that file if the user double-clicks on it." The complication was that the application was not a document-based application. The reason for that was that I have a pretty complex, and working, checkbook application that I wrote as a simple Cocoa app.

But, at least so far, I could not get it to do what it should do, based on Launch Services stuff. Here are some instructions that may work for you. What did work, is to make a new app that is document-based. From that point, I basically followed Hillegass, pp. 163-165, with additional work as described below.

For a document-based application, there are two methods you must implement, for reading and writing your data. You have a choice as to which of 3 versions you use: I chose "writeToURL" and "readFromURL" as shown below.

In addition, I had to do some other things. I added an icon file to my project called "Check.icns." I bound the NSTextField found in the standard MyDocument.xib to an NSString variable for which I did @synthesize in the now familiar way.

And I modified the plist file for the application. I followed Hillegass's instructions. One thing that is weird is that the plist editor uses different identifiers in its view of the plist than are actually in the docs (or in the plist if you look with a standard text editor). Nevertheless, here is a screenshot of what I added.



These can also be set by selecting the Target and doing getInfo...

That got me going. I was able write to disk, and read from disk using the Open menu item. Open Recent also works. But double-clicking on a file icon does not.

For that, you need to do this (assuming that your doc does what mine is doing on the write).



The entire listing for MyDocument.m follows. Notice that no declarations are needed in the header (the methods are already declared in the superclass). Just
@property (retain) NSString *myData;

Now I just need to reimplement my application!

#import "MyDocument.h"

@implementation MyDocument

@synthesize myData;
NSError *e;

- (id)init
{
self = [super init];
if (self) {
}
return self;
}

- (NSString *)windowNibName
{
return @"MyDocument";
}

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

-(BOOL)writeToURL:(NSURL *)url
ofType:(NSString *)typeName
error:(NSError **)outError{
NSString *s = [NSString
stringWithString:@"some fake data"];
[s writeToURL:url
atomically:YES
encoding:NSUTF8StringEncoding
error:&e];
NSLog(@"write %@ %@", url, typeName);
// error stuff not implemented
return YES;
}

-(BOOL)readFromURL:(NSURL *)url
ofType:(NSString *)typeName
error:(NSError **)outError{
NSString *s = [NSString
stringWithContentsOfURL:url
encoding:NSUTF8StringEncoding
error:&e];
NSLog(@"read %@", s);
[self setMyData:s];
// error stuff not implemented
NSLog(@"myData %@", myData);
return YES;
}

@end