如何将NSLog转换为文件

Vov*_*4yk 57 iphone objective-c ios

是否可以将每个NSLog不仅写入控制台,还可以写入文件?我想无需更换准备这个NSLogsomeExternalFunctionForLogging.

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

Jan*_*ano 86

选项1:使用ASL

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

选项2:写入文件

假设您正在模拟器上运行,并且您不想使用Console.app.您可以使用freopen将错误流重定向到您喜欢的文件:
freopen([path cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
有关详细信息,请参阅此说明和示例项目.

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

// 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
Run Code Online (Sandbox Code Playgroud)

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

#import "Log.h"
Run Code Online (Sandbox Code Playgroud)

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

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];
}
Run Code Online (Sandbox Code Playgroud)

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

append(msg);
Run Code Online (Sandbox Code Playgroud)

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


Raf*_*fAl 78

有一个更容易的方法.以下是将NSLog输出重定向到应用程序Documents文件夹中的文件的方法.当您想要在开发工作室之外测试应用程序时,这非常有用,可以从Mac上拔下.

ObjC:

- (void)redirectLogToDocuments 
{
     NSArray *allPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     NSString *documentsDirectory = [allPaths objectAtIndex:0];
     NSString *pathForLog = [documentsDirectory stringByAppendingPathComponent:@"yourFile.txt"];

     freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}
Run Code Online (Sandbox Code Playgroud)

迅速:

func redirectLogToDocuments() {

    let allPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    let documentsDirectory = allPaths.first!
    let pathForLog = documentsDirectory.stringByAppendingString("/yourFile.txt")

    freopen(pathForLog.cStringUsingEncoding(NSASCIIStringEncoding)!, "a+", stderr)
}
Run Code Online (Sandbox Code Playgroud)

执行此方法后,NSLog(ObjC)或print(Swift)生成的所有输出都将转发到指定文件.要打开已保存的文件Organizer,浏览应用程序的文件并保存Application Data在文件系统中的某个位置,而不是简单地浏览到Documents文件夹.

  • 我认为 NSLog 只写入 stderr。 (2认同)

Jaa*_*akL 9

我找到了解决问题的最简单方法:登录iPhone上的文件.无需更改任何NSLog代码或更改记录器本身,只需将这4行添加到didFinishLaunchingWithOptions,并确保在您的构建设置中,实时发布不会激活此功能(我为此添加了LOG2FILE标志).

#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
Run Code Online (Sandbox Code Playgroud)


小智 8

将JaakL的答案翻译成Swift,无论如何其他人也需要它

在应用程序的某个位置运行此代码,从那时起它将所有NSLog()输出存储到文档目录中的文件中.

let docDirectory: NSString = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as NSString
let logpath = docDirectory.stringByAppendingPathComponent("YourFileName.txt")
freopen(logpath.cStringUsingEncoding(NSASCIIStringEncoding)!, "a+", stderr)
Run Code Online (Sandbox Code Playgroud)

额外:如何使用Xcode查找日志文件:
您只需从Xcode访问日志:Windows>设备>选择您的应用程序> InfoWheelButton>下载容器.使用finder查看文件:在文件上单击鼠标右键>显示包内容> appdata> documents>文件是


Mar*_*n S 5

斯威夫特4版本

let docDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let logpathe = docDirectory.appendingPathComponent("Logerr.txt")
freopen(logpathe.path.cString(using: .ascii)!, "a+", stderr)
let logpatho = docDirectory.appendingPathComponent("Logout.txt")
freopen(logpatho.path.cString(using: .ascii)!, "a+", stdout)
Run Code Online (Sandbox Code Playgroud)

Swift 的输出print()将在stdout