echo Does Not Work with NSTask and readInBackgroundAndNotify

219 views Asked by At

I have the following Obj-C code and its log output. Can anyone tell me why I'm not getting any output from the NSFileHandle?

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    [self performSelectorInBackground:@selector(startTask:) withObject:nil];
}

- (void) startTask: (id) sender
{
    NSPipe *pipe = [[NSPipe alloc] init];
    NSFileHandle *fh = pipe.fileHandleForReading;

    [fh readInBackgroundAndNotify];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(output:) name:NSFileHandleReadCompletionNotification object:fh];

    NSTask *echoTask = [[NSTask alloc] init];

    echoTask.standardOutput = pipe;
    echoTask.standardError = [[NSPipe alloc] init];
    echoTask.launchPath = @"/bin/echo";
    echoTask.arguments = @[@"hello world!"];

    NSLog(@"launching...");
    [echoTask launch];
    [echoTask waitUntilExit];
    NSLog(@"finished.");
}

- (void) output:(NSNotification *)notification
{
    NSFileHandle *fh = notification.object;
    NSLog(@"fh: %@", fh);

    NSString *output = [[NSString alloc] initWithData:[fh readDataToEndOfFile] encoding:NSUTF8StringEncoding];

    NSLog(@"output: '%@'", output);
}

@end

log:

2014-12-16 10:19:58.154 SubProcess2[14893:704393] launching...
2014-12-16 10:19:58.165 SubProcess2[14893:704393] fh: <NSConcreteFileHandle: 0x6080000e9e80>
2014-12-16 10:19:58.165 SubProcess2[14893:704393] output: ''
2014-12-16 10:19:58.166 SubProcess2[14893:704393] finished.

If I do it synchronously or using the approach in https://stackoverflow.com/a/16274541/1015200 I could get it to work. Any other techniques and variations(such as launching task without performSelectorInBackground) have failed. I really want to see if I can get it to work using the notification. So if I can get any help that'd be great.

1

There are 1 answers

0
CRD On BEST ANSWER

The data that has already been read is passed to the notification in the userInfo dictionary under the key NSFileHandleNotificationDataItem, you should be accessing that and not attempting to read further data. E.g. something like:

- (void) output:(NSNotification *)notification
{
   NSString *output = [[NSString alloc]
                      initWithData:notification.userInfo[NSFileHandleNotificationDataItem] 
                          encoding:NSUTF8StringEncoding];

   NSLog(@"output: '%@'", output);
}

HTH