Search code examples
objective-ccocoahttp-redirectconsolenslog

How can I easily redirect the console output in a NSTextView?


Suppose you have the code of a Cocoa app which logs its own messages through NSlogs and printfs to the Console output. My goal is to redirect all this output into a separate NSWindow in a NSView.

How can I achieve this in a way that

  • minimizes the amount of code to rewrite
  • makes it possible to revert back
  • maximizes the reuse of written code

(the usual software engineering guide lines)?


Solution

  • Here is the solution I came up with:

    1. Create an NSWindowController that has a NSTextView as an outlet (let's call this A)
    2. Create a Singleton class (let's call this B) that encapsulates an A object and provides some methods for sending strings to A (which appends it to its NSTextView) by reading a file (which contains all the loggings) using readInBackgroundAndNotify from NSFileHandle. When notified it calls the appending method. It has a method for starting the logging on file as well, which uses freopen(3) to redirect some stream (stderr and stdout atm) to a file in append mode.
    3. In the project just call the starting logging method of B (no needs of instantiation, but I guess it really does not matter) after importing it.

    This solution was created considering both Joshua Nozzi's answer and tlindner's one, and combines them. I have and encapsulated solution that respects the three requests in the question (I have to add only a line of code, I can revert back easily and I can use this solution in other apps too). I noticed that maybe sometimes it can be wrong to have an NSWindowController encapsulated this way (whereas all the other ones are managed by some super-controller).

    I finally opted for the file solution since it is very easy to implement and more Cocoa-like than tlindner's one. Also it gives the opportunity to have a logging file that persists on the disk. But of course I may have missed something, point that to me in the comments please ^^