Search code examples
objective-ciosstdoutnsfilehandle

Objective C print stdout to UIAlertView


I have a C function that prints to stdout using fprintf, and I'm attempting to display the contents of stdout in a UIAlertView. My code is as follows:

NSFileHandle *stdoutFileHandle = [NSFileHandle fileHandleWithStandardOutput];
NSData *stdoutData = [stdoutFileHandle availableData];
NSString *stdoutString = [[NSString alloc] initWithData:stdoutData encoding:NSASCIIStringEncoding];

UIAlertView *stdoutAlert = [[UIAlertView alloc] initWithTitle:@"STDOUT OUTPUT" message:stdoutString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[stdoutAlert show];

I'm getting the following error when I run my code.

Terminating app due to uncaught exception 'NSFileHandleOperationException', reason: '[NSConcreteFileHandle availableData]: Bad file descriptor'

I get an equivalent error when I replace [stdoutFileHandle availableData] with [stdoutFileHandle readDataToEndOfFile].


Solution

  • The problem is you are reading from a output stream. To make this work you need to trick stdout to write it's contents to an input stream instead of to the console.

    I know the old C way to do this, but you're not gonna like it. This uses pipe() and dup2().

    int pipefd[2];
    
    pipe(pipefd);
    dup2(pipefd[1], STDOUT_FILENO);
    close(pipefd[1]);
    

    At this point anything written to stdout can be read by pipefd[0]. At that point you can use -initWithFileDescriptor: to read from pipefd[0].

    NSFileHandle *stdoutReader = [[NSFileHandle alloc] initWithFileDescriptor:pipefd[0]];
    

    Note, you will want to do lots of error checking. Hope that helps.