Чтение данных из NSTask Pipe по мере их появления

Пока у меня есть этот код, цель состоит в том, чтобы воздействовать на определенные выходные данные моего NSTask. По сути это (My NSTask) программа, выводящая строки в консоль с течением времени. Я хочу иметь возможность вызвать метод в моем приложении Cocoo Objective-C, когда на консоли отображается определенная строка. Я думаю, что нужно передать вывод консоли моему приложению, которое проверяет, требует ли переданная строка действия.

    NSPipe *pipe = [NSPipe pipe];
    NSFileHandle *file = pipe.fileHandleForReading;

    self.task = [[NSTask alloc] init];

    [self.task setStandardOutput: pipe];
    [self.task setStandardError: [self.task standardOutput]];

    self.task.launchPath = @"/usr/local/bin/taskThing";
    self.task.arguments = @[@"taskArg"];

    [self.task launch];


    NSMutableData *data = [NSMutableData dataWithCapacity:512];
    while ([self.task isRunning]) {
        [data appendData:[file availableData]];
    }
    [file closeFile];

    NSString *taskOut = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"task returned: %@ END", taskOut);

Это в основном «выводит из строя» приложение, поскольку цикл while заставляет его просто продолжать чтение, пока я не убью процесс NSTasks. Когда я завершаю процесс, все записанные выходные данные задачи регистрируются. Так что это работает, я хочу иметь возможность действовать на выходах Tasks по мере их появления, задача будет продолжать выполняться, поэтому я не могу дождаться ее остановки, прежде чем получать переданные данные. Любые идеи?

PS. Я только что видел упоминание о waitForDataInBackgroundAndNotify, надеюсь, это поможет, изучая его.


person Marcus    schedule 02.10.2014    source источник


Ответы (1)


Я больше смотрел на waitForDataInBackgroundAndNotify. В приведенном выше коде после запуска задачи я удалил все последующие строки и заменил их уведомлением Observer

NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;

self.task = [[NSTask alloc] init];

[self.task setStandardOutput: pipe];
[self.task setStandardError: [self.task standardOutput]];

self.task.launchPath = @"/usr/local/bin/taskThing";
self.task.arguments = @[@"taskArg"];

[self.task launch];


[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outData:) 
name:NSFileHandleDataAvailableNotification object:initialOutputFile];

[file waitForDataInBackgroundAndNotify];

В новом методе; "outData:"

- (void)outData:(NSNotification *)notification {
NSFileHandle *outputFile = (NSFileHandle *) [notification object];
NSData *data = [outputFile availableData];

if([data length]) {
    NSString *temp = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"Here: %@", temp);
}

[outputFile waitForDataInBackgroundAndNotify];

}

Все это было основано на этом вопросе

person Marcus    schedule 02.10.2014