I wanted to display output from Process() to NSTextView in real time. Below are my code snippets:
func displayOutput (_ task:Process) {
let outputPipe = Pipe()
setvbuf(stdout, nil, _IONBF, 0)
dup2(outputPipe.fileHandleForWriting.fileDescriptor, STDOUT_FILENO)
task.standardOutput = outputPipe
outputPipe.fileHandleForReading.readabilityHandler = { pipe in
if let outputString = String(data: pipe.availableData, encoding: String.Encoding.utf8) {
if outputString.count > 0 {
DispatchQueue.main.async(execute: {
print(outputString, separator: "\n", to: &self.outputTextView.string)
let range = NSRange(location:self.outputTextView.string.count,length:0)
	self.outputTextView.scrollRangeToVisible(range)
}
}
}
}
}
The above code snippets only works in debug mode. Nothing displays on the NSTextView besides the initial text when it's in release mode.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I wasn't able to get real time output from NSTask to NSTextView in release mode. Already flushed the stdout as stated in https://developer.apple.com/forums/thread/112444.
Below is a snippet of my code:
func displayOutput ( task:Process) {
let outputPipe = Pipe()
setvbuf(stdout, nil, IONBF, 0)
dup2(outputPipe.fileHandleForReading.fileDescriptor, STDOUT_FILENO)
task.standardOutput = outputPipe
outputPipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
NotificationCenter.default.addObserver(forName: NSNotification.Name.NSFileHandleDataAvailable, object: outputPipe.fileHandleForReading , queue: nil) { notification in
let output = outputPipe.fileHandleForReading.availableData
let outputString = String(data: output, encoding: String.Encoding.utf8) ?? ""
if outputString.count > 0 {
DispatchQueue.main.async(execute: {
let previousOutput = self.outputTextView.string
let nextOutput = previousOutput + "\n" + outputString
self.outputTextView.string = nextOutput
let range = NSRange(location:nextOutput.count,length:0)
self.outputTextView.scrollRangeToVisible(range)
})
}
outputPipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
}
}