Group Group Group Group Group Group Group Group Group

Working with stderr and stdout as strings

I’ve spent an absolutely stupid number of days trying to figure this out, which probably means I’m missing something obvious because surely if someone had ever in the history of the world wondered how to do it, I would have found the question they asked by now.

I need to know how to work with the standard output/standard error data that is output to the console as text strings that can be parsed.

I know how to parse text data.
I know how to pipe stdout/stderr data to display in a textfield or save to a file.
I know how to convert text strings that are displayed in a textfield into an array and from there parse it into strings and work with it.

What I don’t know how to do is work with the console output data as text without piping it to a textfield first.

(I’m not even kidding when I say that at this point, I’m on the verge of putting a hidden text field on my app interface as a workaround. If it wouldn’t screw up all my autolayout constraints after I finally got them set in stone, I’d do it.)

What I keep bumping up against are issues like this:

		let outHandle = pipe.fileHandleForReading
		outHandle.waitForDataInBackgroundAndNotify()
		var obs1 : NSObjectProtocol!
		obs1 = NotificationCenter.default
			.addObserver(
				forName: NSNotification.Name.NSFileHandleDataAvailable,
				object: outHandle, queue: nil) {
					notification -> Void in
					let data = outHandle.availableData
					if data.count > 0 {
						if let str = NSString(data: data, encoding: String.Encoding.utf8.rawValue) {
							self.outputLog.string += ("\(str)")

If outputLog were an NSTextField, this would be perfectly displayed. But outputLog is a string variable, and when I try to use it in another method to parse it as text, I get a fatal error because that method is getting nil when trying to read it.

I’ve been through so many variations on this same basic code that I can’t even remember what all errors I keep bumping up against. Mostly they come up nil when I try to call the function, or I get type safety errors because I’m trying to make an NSString into a String.

I have to assume that the fact that I can’t find any similar questions means I’m missing something super obvious, but I just can’t seem to make the console output data parse-able without first piping it to a text field and then reading it from that text field, which seems like a really convoluted way to go about anything.

Hi @ncrusher,
to use stdout and stderr you need to use the OutputStreamType protocol.

public struct StandardErrorOutputStream: TextOutputStream {
    public mutating func write(_ string: String) { fputs(string, stderr) }
}

public var errStream = StandardErrorOutputStream()

Now to print to the stdErr, use

print("Some message to stdErr", to: &errStream)

The reason for this snippet is for you to try a different approach, you can use the standard functions.
cheers,

Thank you! I actually did eventually get this working, so it’s all good. Thanks so much!