iOS 将Log日志输出到文件中保存

对于那些做后端开发的工程师来说,看LOG解Bug应该是理所当然的事,但我接触到的移动应用开发的工程师里面,很多人并没有这个意识,查Bug时总是一遍一遍的试图重现,试图调试,特别是对一些不太容易重现的Bug经常焦头烂额。而且iOS的异常机制比较复杂,Objective-C的语言驾驭也需要一定的功力,做出来的应用有时候挺容易产生崩溃闪退。一遍一遍的用XCode取应用崩溃记录、解析符号,通常不胜其烦,有时还对着解析出来的调用栈发呆,因为程序当时的内部状态常常难以看明白,只能去猜测。 

对于真机,日志没法保存,不好分析问题。所以有必要将日志保存到应用的Docunment目录下,并设置成共享文件,这样才能取出分析。 
首先是日志输出,分为c的printf和标准的NSLog输出,printf会向标准输出(sedout)打印,而NSLog则是向标准出错(stderr),我们需要同时让他们都将日志打印到一个文件中。 
例子: 
freopen(“xx.log”,”a+”,stdout); 
freopen(“xx.log”,”a+”,stderr); 
具体做法:

#pragma mark - 用户方法,将nslog的输出信息写入到dr.log文件中 
// 将NSlog打印信息保存到Document目录下的文件中 
//此函数要在- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions中调用,这个函数在AppDelegate.m中实现的。

- (void)redirectNSlogToDocumentFolder
{
    NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
   NSString *documentDirectory = [paths objectAtIndex:0];
   NSString *fileName = [NSStringstringWithFormat:@"dr.log"];//注意不是NSData!
   NSString *logFilePath = [documentDirectory stringByAppendingPathComponent:fileName];
    //先删除已经存在的文件
   NSFileManager *defaultManager = [NSFileManagerdefaultManager];
    [defaultManagerremoveItemAtPath:logFilePath error:nil];

    // 将log输入到文件
    freopen([logFilePathcStringUsingEncoding:NSASCIIStringEncoding],"a+", stdout);
    freopen([logFilePathcStringUsingEncoding:NSASCIIStringEncoding],"a+", stderr);
}


   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

此函数要在- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions 
中调用,这个函数在AppDelegate.m中实现的。 
/*********************************************************************
//当真机连接Mac调试的时候把这些注释掉,否则log只会输入到文件中,而不能从xcode的监视器中看到。 
// 如果是真机就保存到Document目录下的dr.log文件中 
UIDevice *device = [UIDevicecurrentDevice]; 
if (![[device model]isEqualToString:@”iPad Simulator”]) { 
// 开始保存日志文件 
[selfredirectNSlogToDocumentFolder]; 

/*********************************************************************/

最后配置共享文件夹: 
在应用程序的Info.plist文件中添加UIFileSharingEnabled键,并将键值设置为YES。将您希望共享的文件放在应用程序的 Documents目录。一旦设备插入到用户计算机,iTunes9.1就会在选中设备的Apps标签中显示一个File Sharing区域。此后,用户就可以向该目录添加文件或者将文件移动到桌面计算机中。如果应用程序支持文件共享,当文件添加到Documents目录后,应用程序应该能够识别并做出适当响应。例如说,应用程序可以将新文件的内容显示界面上。请不要向用户展现目录的文件列表并询问他们希望对文件执行什么操作。 
就是说,一旦设备连接上电脑,可以通过iTune查看指定应用程序的共享文件夹,将文件拷贝到你的电脑上看。


iOS中打印日志显示系统详细时间,类名,行号及打印值

Q:如何打印当前的函数和行号? 
A:我们可以在打印时使用一些预编译宏作为打印参数,来打印当前的函数和行号。如:

NSLog(@"%s:%d obj=%@", __func__, __LINE__, obj);
   
   
  • 1
  • 1

其中funcLINE都是预编译的宏,编译时会分别替换为当前函数和当前行号。 
下面是一些常用于打印日志的宏。


    宏              说明
__func__             打印当前函数或方法,c字符串
__LINE__             打印当前行号,整数
__FILE__             打印当前文件路径,c字符串
__PRETTY_FUNCTION__  打印当前函数或方法(在C++中会包含参数类型),c字符串
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Q:如何打印一个类名,消息名,当前堆栈信息? 
A:你可以使用以下方法在运行时动态获取这些信息。


          代码                      说明
NSStringFromSelector(SEL)           获取selector的名字
NSStringFromSelector(_cmd)          获取当前方法名
NSStringFromClass([object class])   获取object的类名
NSThread callStackSymbols]          获取当前线程的栈,是一个NSArry,包含堆栈中所有函数名。

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Q:如何将日志打印到一个文件 
A:可以使用freopen函数重定向标准输出和标准出错文件。因为printf函数会向标准输出(stdout)打印,而NSLog函数会向标准出错(stderr)打印。重新定向标准输出(stdout)和标准出错(stderr)到一个文件将会使他们打印日志到一个文件中。

freopen("/tmp/log.txt", "a+", stdout);
freopen("/tmp/log.txt", "a+", stderr);
   
   
  • 1
  • 2
  • 1
  • 2
#define NSLog(FORMAT, ...) {\

                            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];\

                            [dateFormatter setDateStyle:NSDateFormatterMediumStyle];\

                            [dateFormatter setTimeStyle:NSDateFormatterShortStyle];\

                            [dateFormatter setDateFormat:@"HH:mm:ss:SSSSSS"]; \

                            NSString *str = [dateFormatter stringFromDate:[NSDate date]];\

                            [dateFormatter release];\

                            fprintf(stderr,"[--%s--]*[--%s--]*[--%s:%d--]\n",[str UTF8String], [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String],[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__);\

                            }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17


转载自 :http://blog.csdn.net/levilly/article/details/52757671

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值