在模拟器中,我们可以使用终端的tail命令(tail -f xxx.log)对这个文件进行实时查看,就如同我们在Xcode的输出窗口中看到的那样,你还可以结合grep命令进行实时过滤查看,非常方便在大量的日志信息中迅速定位到我们要的日志信息。
FILE * freopen ( const char * filename, const char * mode, FILE * stream );
具体代码如下:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *loggingPath = [documentsPath stringByAppendingPathComponent:@"/xxx.log"];
//redirect NSLog
freopen([loggingPath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
这样我们就可以把可获取的日志文件发送给服务端或者通过itunes共享出来。但是由于iOS严格的沙盒机制,我们无法知道stderr原来的文件路径,也无法直接使用沙盒外的文件,所以freopen无法重定向回去,只能使用第1点所述的dup和dup2来实现。
// 重定向
int origin1 = dup(STDERR_FILENO);
FILE * myFile = freopen([loggingPath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
// 恢复重定向
dup2(origin1, STDERR_FILENO);
使用GCD的dispatch Source重定向方式
具体代码如下:
- (dispatch_source_t)_startCapturingWritingToFD:(int)fd {
int fildes[2];
pipe(fildes); // [0] is read end of pipe while [1] is write end
dup2(fildes[1], fd); // Duplicate write end of pipe "onto" fd (this closes fd)
close(fildes[1]); // Close original write end of pipe
fd = fildes[0]; // We can now monitor the read end of the pipe
char* buffer = malloc(1024);
NSMutableData* data = [[NSMutableData alloc] init];
fcntl(fd, F_SETFL, O_NONBLOCK);
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0));
dispatch_source_set_cancel_handler(source, ^{
free(buffer);
});
dispatch_source_set_event_handler(source, ^{
@autoreleasepool {
while (1) {
ssize_t size = read(fd, buffer, 1024);
if (size <= 0) {
break;
}
[data appendBytes:buffer length:size];
if (size < 1024) {
break;
}
}
NSString *aString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//printf("aString = %s",[aString UTF8String]);
//NSLog(@"aString = %@",aString);
// Do something
}
});
dispatch_resume(source);
return source;
}
日志同步/上传
重定向或者存储的数据可以传到服务端或者通过server同步到网页上,就可以更方便的看到这些数据了。
如果想再网页端实时查看日志,可以在App内置一个小型http web服务器。GitHub上开源的项目有GCDWebServer,可以使用该工具,在APP开启webserver服务,并在同一局域网下,使用http://localhost:8080来请求最新日志了。










