In my ViewController, I have:
@IBOutlet var ProgressView: NSTextView!
I created this to display all the output from the command that I'd like to run.
In separate file (Class), I run command line program with some arguments for options by using Process. I referenced below from some other answers found in this stackoverflow, but trying to arrange it so that I can output the results from execution in main UI.
Below is as much as I am editing so far...
class Command: Process {
var run = Process()
func runCommand(cmd: String, args: [String]) -> (output: [String], error: [String], exitCode: Int32) {
var output: [String] = []
var error: [String] = []
run.launchPath = cmd
run.arguments = args
let outpipe = Pipe()
run.standardOutput = outpipe
let errpipe = Pipe()
run.standardError = errpipe
let outHandle = outpipe.fileHandleForReading
outHandle.readabilityHandler = { outpipe in
if let line = String(data: outpipe.availableData, encoding: String.Encoding.utf8) {
// Send output (line) to ProgressView in ViewController
}
else {
// Error
}
}
run.launch()
return (output, error, status) }
How can I send each output (line) to ProgressView in ViewController?
****EDIT****
I have worked on this today and progressed a little bit more. I now reached NotificationCenter to create path from one Class to another after learning from past post in stack overflow, but not quite yet working.
In my ViewController: override func viewDidLoad() { super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(appendToProgressView(notification:)), name: NSNotification.Name(rawValue: "append"), object: nil) }
@IBOutlet var ProgressView: NSTextView!
func appendToProgressView(notification: Notification) { Logger.info("Received Notification")
if let outputMessage = notification.userInfo?["output"] as? String {
Logger.info("outputMessage = \(outputMessage)")
self.ProgressView.textStorage?.append(NSAttributedString(string: outputMessage))
}
else {
let errMessage = notification.userInfo?["error"] as? String
Logger.info("errMessage = \(errMessage)")
self.ProgressView.textStorage?.append(NSAttributedString(string: errMessage!))
}
In my other Class, Command: // This is where it runs command line tasks by using Process. I referenced some information on stack overflow and edited for my needs.
var run = Process()
var output: [String] = []
var error: [String] = []
run.launchPath = cmd
run.arguments = args
let outpipe = Pipe()
run.standardOutput = outpipe
let errpipe = Pipe()
run.standardError = errpipe
let outHandle = outpipe.fileHandleForReading
let errHandle = errpipe.fileHandleForReading
outHandle.readabilityHandler = { outpipe in
if let outline = String(data: outpipe.availableData, encoding: String.Encoding.utf8) {
Logger.info("outline = \(outline)")
let outDataDict: [String : String] = ["output" : outline]
NotificationCenter.default.post(name: Notification.Name(rawValue: "append"), object: nil, userInfo: outDataDict)
}
else {
// NEED MORE WORK
}
}
errHandle.readabilityHandler = { errpipe in
if let errline = String(data: errpipe.availableData, encoding: String.Encoding.utf8) {
Logger.info("errline = \(errline)")
let errDataDict: [String : String] = ["error" : errline]
NotificationCenter.default.post(name: Notification.Name(rawValue: "append"), object: nil, userInfo: errDataDict)
}
else {
// NEED MORE WORK
}
run.launch()
...
run.waitUntilExit()
...
In ViewController, it finally responded, and appended some outputted text into my NSTextView! in ViewController, but only worked with errline case, which is the error. For some reasons, outline is not working.
I am wondering where I am missing and causing non error case to not work to append to my NSTextView!.