1

I would like that the XCode output (from NSLog() or whatever) is automatically written into a file in the application's folder. In other words, I just want to see the whole content of the XCode area debug into a text file.

I saw some code snippets but each of them avoids the display into XCode (that is unacceptable). I just want to duplicate the debug text to a file... Is there a way to do that ?

EDIT 1 (after trying the Clement's answer) :

I get a linker error : enter image description here

EDIT 2 (how I have implemented the Clement's answer) :

I created a new class called LogHelper :

LogHelper.h :

#define NSLog(args...) _Log(@"DEBUG ", __FILE__,__LINE__,__PRETTY_FUNCTION__,args);
@interface MyCustomLog : NSObject
void _Log(NSString *prefix, const char *file, int lineNumber, const char *funcName, NSString *format,...);
@end

LogHelper.m :

#import "LogHelper.h"

@implementation MyCustomLog : NSObject

void append(NSString *msg){
    // get path to Documents/somefile.txt
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"myCustomLog.txt"];
    // create if needed
    if (![[NSFileManager defaultManager] fileExistsAtPath:path]){
        fprintf(stderr,"Creating file at %s",[path UTF8String]);
        [[NSData data] writeToFile:path atomically:YES];
    }
    // append
    NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:path];
    [handle truncateFileAtOffset:[handle seekToEndOfFile]];
    [handle writeData:[msg dataUsingEncoding:NSUTF8StringEncoding]];
    [handle closeFile];
}

void _Log(NSString *prefix, const char *file, int lineNumber, const char *funcName, NSString *format,...) {
    va_list ap;
    va_start (ap, format);
    format = [format stringByAppendingString:@"\n"];
    NSString *msg = [[NSString alloc] initWithFormat:[NSString stringWithFormat:@"%@",format] arguments:ap];
    va_end (ap);
    fprintf(stderr,"%s%50s:%3d - %s",[prefix UTF8String], funcName, lineNumber, [msg UTF8String]);
    append(msg);
}
@end

And I added #import "LogHelper.h" in myApplication-Prefix.pch.

EDIT 3 (I found a solution) :

  • I set an environment variable called "runningFromXCode" (follow this link to see how to do it) to keep the debug text showing into the console when the app is running from XCode ;

  • I wrote this piece of code into the application:didFinishLaunchingWithOptions: method (source) :

    if (getenv("runningFromXCode") == NULL){
        NSArray *allPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [allPaths objectAtIndex:0];
        NSString *pathForLog = [documentsDirectory stringByAppendingPathComponent:@"log.txt"];
    
        freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
    }
    
Community
  • 1
  • 1
Jonathan F.
  • 2,357
  • 4
  • 26
  • 44

1 Answers1

1
#define NSLog(args...) _Log(@"DEBUG ", __FILE__,__LINE__,__PRETTY_FUNCTION__,args);
    @interface MyCustomLog : NSObject
    void _Log(NSString *prefix, const char *file, int lineNumber, const char *funcName, NSString *format,...);
    @end

    @implementation MyCustomLog
    void append(NSString *msg){
        // get path to Documents/somefile.txt
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"myCustomLog.txt"];
        // create if needed
        if (![[NSFileManager defaultManager] fileExistsAtPath:path]){
            fprintf(stderr,"Creating file at %s",[path UTF8String]);
            [[NSData data] writeToFile:path atomically:YES];
        }
        // append
        NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:path];
        [handle truncateFileAtOffset:[handle seekToEndOfFile]];
        [handle writeData:[msg dataUsingEncoding:NSUTF8StringEncoding]];
        [handle closeFile];
    }

    void _Log(NSString *prefix, const char *file, int lineNumber, const char *funcName, NSString *format,...) {
        va_list ap;
        va_start (ap, format);
        format = [format stringByAppendingString:@"\n"];
        NSString *msg = [[NSString alloc] initWithFormat:[NSString stringWithFormat:@"%@",format] arguments:ap];
        va_end (ap);
        fprintf(stderr,"%s%50s:%3d - %s",[prefix UTF8String], funcName, lineNumber, [msg UTF8String]);
        append(msg);
    }
    @end

stackoverflow.com/questions/7271528/how-to-nslog-into-a-file

Community
  • 1
  • 1
Clement Prem
  • 3,112
  • 2
  • 23
  • 43
  • This code is taken from the following question without attribution: http://stackoverflow.com/questions/7271528/how-to-nslog-into-a-file – trojanfoe Jun 26 '14 at 11:19
  • @trojanfoe thanks for the link. I used it in a project but couldn't find the source. Answer is updated with attribution – Clement Prem Jun 26 '14 at 11:32
  • @Erzékiel the same code works for me. Can you update ur question with how did you implement and use the MyCustomLog call? – Clement Prem Jun 27 '14 at 08:21
  • @Clement Sorry for the delay, please see the edit 2. – Jonathan F. Jul 07 '14 at 09:16
  • @Erzékiel I checked ur code. There is nothing wrong in the code. I checked in iPhone & simulator. You just have to call NSLog(arg), in you classes. That what ur doing right? – Clement Prem Jul 11 '14 at 11:11
  • Yes, but I'm still having the two linkers errors (edit 1)... So I can't build with the `#import "LogHelper.h"`line into `myApplication-Prefix.pch`. As you can see in the edit 1, the errors fired into `OrdoScanViewController`. it's a third party C++ library, and I spent several hours to integrate it, because it fired me similar linker errors... – Jonathan F. Jul 15 '14 at 07:42