Calling Applescript from Objective-C and Cocoa. |
23 July 2005 |
Why do I want to do this?
I was writing the draft for the
Image Colour Metadata
Automator action when I was thinking of a way to add metadata to existing
file types (images) without Spotlight plugins.
Since it seems that only one Spotlight importer is used per filetype
(please correct me if I'm wrong) I couldn't use a Spotlight plugin
for this in any case since the filetype was an existing one, not
a newly created one.
So I had to come up with another way of doing this, and the
only way I could think of was to add Finder comments (now Spotlight
comments) to the files.
How did I do this?
I looked for a few days to find a nice method and found nothing good.
Finder events and the other methods I found all seemed difficult and
old to me, a newbie Cocoa programmer. So I forgot about this for a while.
When I came back to it I looked at Applescript and found it could do what I wanted.
Again I found some horrid methods of calling Applescripts, and some not so horrid.
I had great trouble finding a way of passing my required parameters (file and comment)
to the script.
I am sure that for seasoned Cocoa programmers this is nothing new: my
solution was to create the Applescript at runtime when required,
not the nicest or fastest way to do it, but a simple one. The source is below:
/*----------------------------------------------------------------------------*/
/**
* Add metadata comment to the file's current comment.
*
* \param (NSString*) file File path.
* \param toComment:(NSString*) comment The comment to add to the file's comment.
*/
-(void)setCommentForFile:(NSString*)file
toComment:(NSString*)comment
{
NSDictionary *scriptError = [[NSDictionary alloc] init];
NSString *scriptSource = [NSString stringWithFormat:
@"on run\r tell application \"Finder\"\r set theFile to
(\"%@\") as alias\r set newComment to (comment of theFile) &
\"%@\"\r set comment of theFile to newComment\r end tell\r end run\r",
[self carbonPathFromPath:file], comment];
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:scriptSource];
if(![appleScript executeAndReturnError:&scriptError])
NSLog([scriptError description]);
}
The function accepts two parameters (file and comment) and creates an
NSString object containing a static script with the two parameters inserted.
The script is then run using executeAndReturnError.
One more thing...
You will have noticed I don't use the file parameter directly, I do something to it before insertion.
Applescript wants file names specified differently than POSIX names. A function named
CFURLCopyFileSystemPath which converts POSIX
paths to HFS paths. A nice way of doing this with NSString is presented
at this Cocoa Builder post.
This was my first Cocoa project. I bought the following books to help me learn Objective-C and Cocoa:
- "Cocoa Programming For Mac OS X Second Edition" - Aaron Hillegass, ISBN 0-321-21314-9;
- "Core Mac OS X And UNIX Programming" - Mark Dalrymple and Aaron Hillegass, ISBN 0-9740785-0-6;
- "Programming in Objective-C" - Stephen G. Kochan, ISBN 0-672-32586-1;
- "Objective-C Pocket Reference" - Andrew M. Duncan, ISBN 0-596-00423-0.
I am not sure how much coding I will do with Objective-C instead of the usual C++,
but already I like it better than C++ even though I know little about it.
Objective-C seems a lot cleaner than the C++ I've been using for many years!
|