I know how to send data to the task:
NSData *charlieSendData = [[charlieImputText stringValue] dataUsingEncoding:NSUTF8StringEncoding];
[[[task standardInput] fileHandleForWriting] writeData:charlieSendData];
But how do I get what the task responds with??
Elijah
Give an NSPipe
or an NSFileHandle
as the task's standardOutput
, and read from that.
NSTask * list = [[NSTask alloc] init];
[list setLaunchPath:@"/bin/ls"];
[list setCurrentDirectoryPath:@"/"];
NSPipe * out = [NSPipe pipe];
[list setStandardOutput:out];
[list launch];
[list waitUntilExit];
[list release];
NSFileHandle * read = [out fileHandleForReading];
NSData * dataRead = [read readDataToEndOfFile];
NSString * stringRead = [[[NSString alloc] initWithData:dataRead encoding:NSUTF8StringEncoding] autorelease];
NSLog(@"output: %@", stringRead);
Note that if you use a pipe, you have to worry about the pipe filling up. If you provide an NSFileHandle
instead, the task can output all it wants without you having to worry about losing any, but you also get the overhead of having to write the data out to disk.
Swift 3 solution, you can implement a closure that accepts a FileHandle
let process = Process()
process.launchPath = launchPath
process.arguments = arguments
let stdOut = Pipe()
process.standardOutput = stdOut
let stdErr = Pipe()
process.standardError = stdErr
let handler = { (file: FileHandle!) -> Void in
let data = file.availableData
guard let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
else { return}
print(output.components(separatedBy: "\n").first!)
}
stdErr.fileHandleForReading.readabilityHandler = handler
stdOut.fileHandleForReading.readabilityHandler = handler
process.terminationHandler = { (task: Process?) -> () in
stdErr.fileHandleForReading.readabilityHandler = nil
stdOut.fileHandleForReading.readabilityHandler = nil
}
process.launch()
process.waitUntilExit()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With