Jakeas hacks
Jakeas hacks

Reputation: 25

Run a shell command on Objective c and simultaneously get output

Let's say I want to run curl -o http://example.com/file.zip via an Objective C app and I want to have a label or text box containing the download status which gets updated while the command is running. Maybe this could be achieved using dispatch_async, but now sure how. Before marking as duplicate, the methods I found, run the command, and after it has finished you get the output. I want to get the output while it's running, kinda like a terminal emulator.

Upvotes: 2

Views: 743

Answers (1)

Warren Burton
Warren Burton

Reputation: 17372

You need to connect a NSPipe to the NSTask using the standardOutput property and register to receive Data Available notifications.

@interface TaskMonitor: NSObject
@property NSPipe *outputPipe;
@end

@implementation TaskMonitor

-(void)captureStandardOutput:(NSTask *)process {

  self.outputPipe = [NSPipe new];
  process.standardOutput = self.outputPipe;

  //listen for data available
  [self.outputPipe.fileHandleForReading waitForDataInBackgroundAndNotify];

  [[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification object:self.outputPipe.fileHandleForReading queue:nil usingBlock:^(NSNotification * _Nonnull note) {

    NSData *output = self.outputPipe.fileHandleForReading.availableData;
    NSString *outputString = [[NSString alloc] initWithData:output encoding:NSUTF8StringEncoding];

    dispatch_async(dispatch_get_main_queue(), ^{
      // do something with the string chunk that has been received
      NSLog(@"-> %@",outputString);
    });

    //listen again...
    [self.outputPipe.fileHandleForReading waitForDataInBackgroundAndNotify];

  }];

}

@end

Upvotes: 3

Related Questions