Objective c 在Objective c上运行shell命令,同时获取输出

Objective c 在Objective c上运行shell命令,同时获取输出,objective-c,bash,macos,shell,nstask,Objective C,Bash,Macos,Shell,Nstask,假设我想运行curl-ohttp://example.com/file.zip通过Objective C应用程序,我希望有一个标签或文本框,其中包含在命令运行时更新的下载状态。也许这可以通过使用dispatch\u async实现,但现在确定了如何实现。在将我找到的方法标记为复制之前,运行命令,完成后,您将获得输出。我想在它运行时获得输出,有点像终端模拟器 您需要使用standardOutput属性将NSPipe连接到NSTask,并注册以接收可用数据通知 @interface TaskMoni

假设我想运行
curl-ohttp://example.com/file.zip
通过Objective C应用程序,我希望有一个标签或文本框,其中包含在命令运行时更新的下载状态。也许这可以通过使用dispatch\u async实现,但现在确定了如何实现。在将我找到的方法标记为复制之前,运行命令,完成后,您将获得输出。我想在它运行时获得输出,有点像终端模拟器

您需要使用
standardOutput
属性将
NSPipe
连接到
NSTask
,并注册以接收可用数据通知

@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

你好,我刚试过,但有个问题。它运行整个命令,输出得到NSLogged,就像在任何NSTask中一样,然后我在日志上得到无限的
->
,后面没有数据,除了第一个类似的
->
。正如我所说的,我希望每个数据段都有一个
->
,这样我就可以用它来更新UI。Nvm由于某种原因没有在日志上工作,但在我将它连接到UI时工作了!