Question
I am a fledgling mac programmer, and I cannot find a bit of useful documentation on how to call ‘packaged’ shell programs. For example, if you use the wonderful program iSquint and do a ‘show contents’ on the app, you’ll find unix shell apps like ‘ffmpeg’ and ‘qt_export’ in the Resources directory – how the heck can I 1) package apps like that in an Xcode project (cocoa), and 2) how do I ‘call’ it from my program?
Answer
There are a lot of applications that are merely front-ends to common-ish UNIX utilities. One of my favorites is UnRarX. Cocoa actually abstracts almost the entire process for you, so you don’t have to screw around with any pure-C calls to system() or exec(), which are vile, evil little beasties.
You want the good ol’ NSTask class to do this. First, though, copy the tool into your package using Add to Project… from the Project menu, making sure to add to the Target. After that, the rest is actually pretty darned simple. In your code, create an NSTask, set the path to the task, and launch it.
myTask = [[NSTask alloc] init];
myTaskPath = [[NSBundle mainBundle] pathForResource:@"mytool" ofType:nil];
[myTask setLaunchPath:myTaskPath];
[myTask launch];
You can also pass in args using the setArguments: method to NSTask, which expects an NSArray. If you properly retain various bits, you can also use [myTask terminate] to kill it later on. Several of my projects have start and stop buttons that are little more than IBActions that call NSTask @launch@ and terminate methods.
Using unrar as an example:
myTask = [[NSTask alloc] init];
myTaskPath = [[NSBundle mainBundle] pathForResource:@"mytool" ofType:nil];
[myTask setLaunchPath:myTaskPath];
[myTask setArguments:[NSArray arrayWithObjects:@"e",@"file1.rar",@"/path/to/destination"]];
[myTask launch];
..would be the same as:
$ unrar e file1.rar /path/to/destination@
The full documentation for NSTask can be found here.
This is brilliant — is there a Carbon API to accomplish the same (or similar) result?
Unfortunately, I do not speak Carbon. Not sure, by I would have to imagine that (since this is essentially plain old C we’re talking about), it probably centers around the use of system() or exec(). Remember that Carbon is really just native compatibility layer, all of the APIs are still geared for the classic OS.
Post new comment