0

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!.

WeeklyJump
  • 23
  • 5
  • What is the question, how to get the data from one class to another or how to append text to the text view? – Willeke Jun 05 '17 at 09:33
  • @Willeke Hi, thanks for reply. It is both. (1) How can I send each terminal output ran in one Class and pass it to the ViewController. (2) Once ViewController gets that value, how can I append it to the NSTextView? ---I have worked on this today, but so incomplete to update it here yet, it is keep crashing, but I am not very sorted out yet. (@_@) I may edit my Question when it gets a bit better. – WeeklyJump Jun 05 '17 at 09:41
  • These question have been asked before: [Passing Data between View Controllers](https://stackoverflow.com/q/5210535/4244136) and [Appending text to NSTextView in Swift 3](https://stackoverflow.com/q/40478728/4244136). – Willeke Jun 05 '17 at 09:58
  • I got append text one from the link you mentioned, but the first one, Passing Data between ViewControllers isn't quite same as what I am doing I guess. I do not have two ViewController, one is just another Class that runs Process, and what I'd like to do is real time output to be printed in NSTextView! linked and declared in my only ViewController. I updated my post with my today's little progress. – WeeklyJump Jun 05 '17 at 14:29

0 Answers0