使用 NSPipe 进行交互式命令
Using NSPipe for interactive commands
我正在我的 OS X 应用程序中启动一些交互过程,我希望能够从管道读取和写入。
例如:启动进程将等待用户键入命令。当用户完成(又名按下回车)时,进程将 return 一些东西然后再次等待用户。
目前,我使用NSPipe
class进行通信,但问题是调用方法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:
被调用后没有通知。
如何实现通信,即:
启动(并在应用生命周期内保持启动)
支持读写
您需要将换行符附加到您发送到管道的任何命令,就像您以交互方式一样。换行符刷新流缓冲区,通常是命令的 "go" 部分。
但是,我找不到任何参考来重新执行此答案。
我正在我的 OS X 应用程序中启动一些交互过程,我希望能够从管道读取和写入。
例如:启动进程将等待用户键入命令。当用户完成(又名按下回车)时,进程将 return 一些东西然后再次等待用户。
目前,我使用NSPipe
class进行通信,但问题是调用方法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:
被调用后没有通知。
如何实现通信,即:
启动(并在应用生命周期内保持启动)
支持读写
您需要将换行符附加到您发送到管道的任何命令,就像您以交互方式一样。换行符刷新流缓冲区,通常是命令的 "go" 部分。
但是,我找不到任何参考来重新执行此答案。