2015-05-23 3 views
1

Я запускаю некоторый интерактивный процесс внутри своего приложения OS X. Я хочу иметь возможность читать и писать из труб.Использование NSPipe для интерактивных команд

Например: Запуск процесса будет ждать ввода пользователем команды. Когда пользователь закончит (ака нажал enter), процесс вернет что-то, а затем снова ждет пользователя.

На данный момент, я использую NSPipe класс для общения, но проблема в том, когда метод writeData: называется, я должен позвонить closeFile, чтобы получить уведомление NSFileHandleDataAvailableNotification.

Полный код (с измененными пути к папкам) это

dispatch_queue_t taskQueue = 
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); 
    dispatch_async(taskQueue, ^{ 

    task = [[NSTask alloc] init]; 
    [task setStandardOutput: [NSPipe pipe]]; 
    [task setStandardInput: [NSPipe pipe]]; 
    [task setStandardError: [task standardOutput]]; 
    [task setLaunchPath: @"/Users/..."]; 
    [task setArguments:@[@"--interaction"]]; 

    [[[task standardOutput] fileHandleForReading] waitForDataInBackgroundAndNotify]; 

    [[NSNotificationCenter defaultCenter] 
     addObserverForName:NSFileHandleDataAvailableNotification 
        object:[[task standardOutput] fileHandleForReading] 
        queue:nil 
       usingBlock:^(NSNotification *notification){ 
     NSData *output = [[[task standardOutput] fileHandleForReading] availableData]; 
     NSString *outStr = [[NSString alloc] initWithData:output encoding:NSUTF8StringEncoding]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      NSLog(@"avaliable data: %@", outStr); 
      NSString * message = @"IOTCM \"/Users/.../Demo.agda\" None Indirect (Cmd_show_version)"; 
      [[[task standardInput] fileHandleForWriting] 
        writeData:[message dataUsingEncoding:NSUTF8StringEncoding]]; 
     }); 
     [[[task standardOutput] fileHandleForReading] waitForDataInBackgroundAndNotify]; 
    }]; 

    [task launch]; 
    [task waitUntilExit]; 
}); 

Обратите внимание, что я получаю первое уведомление (процесс отвечает), но уведомление не приходит после того, как writeData: вызывается.

Как добиться связи, что:

  1. получает запущен (и остается запущен через приложение жизненного цикла)

  2. запись и чтение поддерживается

+1

Вам не нужна новая строка в конце команды? – Droppy

+0

Может быть? Попробуем и согласимся, если это трюк. И я куплю вам пиво, если это работает :) спасибо! – markich

+0

Если вы живете в Германии, то я откушу вашу руку за пивом ;-) – Droppy

ответ

1

Вы должны добавить newline для любых команд, которые вы отправляете в трубу, так же, как и в интерактивном режиме. Новые строки очищают поток буферов и, как правило, являются частью «go».

Однако я не могу найти ссылки на повторное применение этого ответа.

Смежные вопросы