I have found that AMShellWrapper is very nice for wrapping Command Line Tools. For an example on how to use it, see Andreas Mayer’s code. You might also find my cocoagcalc source code useful.
The key part of using AMShellWrapper is to implement the protocol:
// implement this protocol to control your AMShellWrapper object:
- (void)appendOutput:(NSString *)output;
// output from stdout
- (void)appendError:(NSString *)error;
// output from stderr
// This method is a callback which your controller can use to do other initialization
// when a process is launched.
- (void)processFinished:(id)sender withTerminationStatus:(int)resultCode;
// This method is a callback which your controller can use to do other cleanup
// when a process is halted.
// AMShellWrapper posts a AMShellWrapperProcessFinishedNotification when a process finished.
// The userInfo of the notification contains the corresponding NSTask ((NSTask *), key @"task")
// and the result code ((NSNumber *), key @"resultCode")
// ! notification removed since it prevented the task from getting deallocated
Update: I have found a better way. See this post.
So, probably the easiest way (even if somewhat pokey) to wrap a CLI program with a Cocoa GUI is to use AppleScript as the bridge. For example:
do shell script “cd /Xcode_projects/Debug; ./sample > result.txt”
is the contents of a sample applescript, where result.txt is the output of the CLI, sample is the name of the CLI program. One would use NSTask to run the applescript(in order to run the CLI and generate output).
It turns out the earlier problem I was having with NSPipe wasn’t because of “flushing the buffer” issues. In my project, I was wrapping a command-line C++ program. However, after copying the C++ program to the directory where the Cocoa program resided, the issue seemed to disapper(i.e., I need to test it some more).
Using the NSTask method enables one to create a GUI wrapper around a commandline program. For instance, this code snippet derived from CocoaDev shows how to launch the ls utility:
task = [[NSTask alloc] init];
[task setLaunchPath: @”/bin/ls”];
arguments = [NSArray arrayWithObjects: @”-l”, @”-a”, @”-t”,nil];
[task setArguments: arguments];