首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何NSLog到文件中

如何NSLog到文件中
EN

Stack Overflow用户
提问于 2011-09-01 22:08:11
回答 4查看 62.5K关注 0票数 69

有没有可能将每个NSLog不仅写入控制台,还写入一个文件?我想在不将NSLog替换为someExternalFunctionForLogging的情况下对此进行准备。

替换所有NSLog将是一个真正的问题。也许有可能从控制台解析数据或捕获消息?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-09-05 19:07:06

选项1:使用ASL

NSLog输出日志到ASL (苹果版本的syslog)和控制台,这意味着当你使用iPhone模拟器时,它已经在你的Mac中写入一个文件。如果您想阅读它,请打开应用程序Console.app,然后在filter字段中键入应用程序的名称。要在iPhone设备中执行相同的操作,您需要使用API并进行一些编码。

选项2:写入文件

假设您正在模拟器上运行,并且不想使用Console.app。您可以使用freopen将错误流重定向到您喜欢的文件:

freopen([path cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);

有关详细信息,请参阅此explanation and sample project

或者,您可以使用宏用自定义函数覆盖NSLog。例如,将此类添加到您的项目中:

代码语言:javascript
复制
// file Log.h
#define NSLog(args...) _Log(@"DEBUG ", __FILE__,__LINE__,__PRETTY_FUNCTION__,args);
@interface Log : NSObject
void _Log(NSString *prefix, const char *file, int lineNumber, const char *funcName, NSString *format,...);
@end

// file Log.m
#import "Log.h"
@implementation Log
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]);
    [msg release];
}
@end

并将其导入项目范围,并将以下内容添加到您的<application>-Prefix.pch中:

代码语言:javascript
复制
#import "Log.h"

现在,每次对NSLog的调用都将被替换为您的自定义函数,而无需触及现有的代码。但是,上面的功能只是打印到控制台。要添加文件输出,请将此函数添加到_Log之上:

代码语言:javascript
复制
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:@"logfile.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];
}

并在_Log函数中的fprintf下面添加以下行:

代码语言:javascript
复制
append(msg);

文件写入也适用于你的iPhone设备,但文件将被创建在其中的一个目录中,除非你添加代码将其发送回mac,或者在应用程序内的视图上显示,或者使用iTunes添加文档目录,否则你将无法访问。

票数 93
EN

Stack Overflow用户

发布于 2011-11-21 01:25:39

我找到了这个问题的最简单的解决方案:Logging to a file on the iPhone。不需要更改任何NSLog代码或日志记录器本身,只需将这4行代码添加到您的didFinishLaunchingWithOptions中,并确保在您的构建设置中实时发布不会激活它(我为此添加了LOG2FILE标志)。

代码语言:javascript
复制
#ifdef LOG2FILE
 #if TARGET_IPHONE_SIMULATOR == 0
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
    freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
 #endif
#endif
票数 11
EN

Stack Overflow用户

发布于 2011-09-05 17:12:12

这是我使用的,并且效果很好:

http://parmanoir.com/Redirecting_NSLog_to_a_file

希望能有所帮助。

为了内容的缘故,我只是把它贴在这里

代码语言:javascript
复制
- (BOOL)redirectNSLog { 
     // Create log file 
     [@"" writeToFile:@"/NSLog.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil]; 
     id fileHandle = [NSFileHandle fileHandleForWritingAtPath:@"/NSLog.txt"]; 
     if (!fileHandle) return NSLog(@"Opening log failed"), NO; 
     [fileHandle retain];  

     // Redirect stderr 
     int err = dup2([fileHandle fileDescriptor], STDERR_FILENO); 
     if (!err) return NSLog(@"Couldn't redirect stderr"), NO;  return YES; 
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7271528

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档