iOS中 加强日志输出 开发技术总结
对于那些做后端开发的工程师来说,看LOG解Bug应该是理所当然的事,但我接触到的移动应用开发的工程师里面,很多人并没有这个意识,查Bug时总是一遍一遍的试图重现,试图调试,特别是对一些不太容易重现的Bug经常焦头烂额。而且iOS的异常机制比较复杂,Objective-C的语言驾驭也需要一定的功力,做出来的应用有时候挺容易产生崩溃闪退。一遍一遍的用XCode取应用崩溃记录、解析符号,通常不胜其烦,有时还对着解析出来的调用栈发呆,因为程序当时的内部状态常常难以看明白,只能去猜测。
对于真机,日志没法保存,不好分析问题。所以有必要将日志保存到应用的Docunment目录下,并设置成共享文件,这样才能取出分析。
导入第三方:AFNetWorkinng
- (void)viewDidLoad
{
[super viewDidLoad];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://mobile.ximalaya.com/m/category_tag_list?category=entertainment&device=iPhone&type=album" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"%@", [error localizedDescription]);
}];
}
给其写一个类目:Foundation+Log.m
#import <Foundation/Foundation.h>
@implementation NSDictionary (Log)
//+ (void)load
//{
// NSLog(@"11");
//}
- (NSString *)descriptionWithLocale:(id)locale
{
NSMutableString *str = [NSMutableString string];
[str appendString:@"{\n"];
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[str appendFormat:@"\t%@ = %@, \n", key, obj];
}];
[str appendString:@"}"];
// 删除最后一个,
NSRange range = [str rangeOfString:@"," options:NSBackwardsSearch];
[str deleteCharactersInRange:range];
return str;
}
@end
@implementation NSArray (Log)
- (NSString *)descriptionWithLocale:(id)locale
{
NSMutableString *str = [NSMutableString string];
[str appendString:@"[\n"];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[str appendFormat:@"\t\t%@,\n", obj];
}];
[str appendString:@"]"];
// 删除最后一个,
NSRange range = [str rangeOfString:@"," options:NSBackwardsSearch];
[str deleteCharactersInRange:range];
return str;
}@end
最终效果:
小技巧:iOS - 将控制台Log日志转为输出为文本文件
1.在AppDelegate.m中创建函数实现以下代码块:
- (void)redirectNSlogToDocumentFolder
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:@"MrNSLog.txt"];// 注意不是NSData!
NSString *logFilePath = [documentDirectory stringByAppendingPathComponent:fileName];
// 先删除已经存在的文件
NSFileManager *defaultManager = [NSFileManager defaultManager];
[defaultManager removeItemAtPath:logFilePath error:nil];
// 将log输入到文件
freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stdout);
freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
}
2.在didFinishLaunchingWithOptions中调用 :
[self redirectNSlogToDocumentFolder];
最后配置共享文件夹:
在应用程序的Info.plist文件中添加UIFileSharingEnabled键,并将键值设置为YES。将您希望共享的文件放在应用程序的 Documents目录。一旦设备插入到用户计算机,iTunes9.1就会在选中设备的Apps标签中显示一个File
Sharing区域。此后,用户就可以向该目录添加文件或者将文件移动到桌面计算机中。如果应用程序支持文件共享,当文件添加到Documents目录后,应用程序应该能够识别并做出适当响应。例如说,应用程序可以将新文件的内容显示界面上。请不要向用户展现目录的文件列表并询问他们希望对文件执行什么操作。
每日更新关注:http://weibo.com/hanjunqiang
新浪微博
iOS中 加强日志输出 开发技术总结的更多相关文章
- Android和iOS中Cocos2D日志为什么会出现skip frames
在你运行app在Android或iOS设备或iOS模拟器中时,日志里往往会出现一行: I/Choreographer(28956): Skipped 159 frames! The applicati ...
- springboot项目中的日志输出
#修改默认输出级别,trace < debug < info < warn < errorlogging.level.com.lagou=trace#控制台输出logging. ...
- 【Django】Django开发中的日志输出
开发环境:Ubuntu16.04+Django 1.11.9+Python2.7 一:使用自定义函数输出日志到log文件: import time def print_log(log): file_o ...
- Andriod学习笔记5:通过NDK在C++中实现日志输出
开发环境 android studio 1.5.1 实现步骤 新建android项目 项目名称为AndroidCLog,选择Empty Activity模板,其他默认即可. 下载配置ndk 在项目上右 ...
- ios中三种多线程的技术对比
1.NSThread 使用较少 在NSThread调用的方法中,同样要使用autoreleasepool进行内存管理,否则容易出现内存泄露. 使用流程:创建线程-->启动线程 2.NSOpera ...
- MySQL系列详解三:MySQL中各类日志详解-技术流ken
前言 日志文件记录了MySQL数据库的各种类型的活动,MySQL数据库中常见的日志文件有 查询日志,慢查询日志,错误日志,二进制日志,中继日志 .下面分别对他们进行介绍. 查询日志 1.查看查询日志变 ...
- docker中tomcat日志输出自定义
一,默认tomcat日志配置文件 /data/tomcat/conf/logging.properties 1,修改tomcat/conf下的logging.properties [root@harb ...
- springboot+logback日志输出企业实践(上)
目录 1.引言 2.logback简介 3. springboot默认日志框架-logback 3.1 springboot示例工程搭建 3.2 日志输出与基本配置 3.2.1 日志默认输出 3.2. ...
- Log4j中配置日志文件相对路径
方法一. 解决的办法自然是用相对路径代替绝对路径,其实log4j的FileAppender本身就有这样的机制,如:log4j.appender.logfile.File=${WORKDIR}/logs ...
随机推荐
- 在移动端画出真正的1px边框
一.问题 写H5的样式时候,设置元素的边框为1px,不幸的事情在IOS设备上发生了,设计师会说,咦,边框怎么那么大,这是2px了吧?改成1px.我明明设置成1px了啊. 二.为什么边框变粗了? ...
- Vue-起步篇:Vue与React、 Angular的区别
毋庸置疑,Vue.React. Angular这三个是现在比较火的前端框架.这几个框架都各有所长,选择学习哪种就得看个人喜好或者实际项目了.相比之下, Vue 是轻量级且容易学习掌握的. 1.Vue和 ...
- DDL/DML/DCL区别概述
DDL DDL的概述 DDL(Data Definition Language 数据定义语言)用于操作对象和对象的属性,这种对象包括数据库本身,以及数据库对象,像:表.视图等等,DDL对这些对象和属性 ...
- Web缓存(一) - HTTP协议缓存
为什么要使用 Web 缓存 Web缓存一般分为浏览器缓存.代理服务器缓存以及网关缓存,本文主要讲的是 浏览器缓存,其它两种缓存大家自行去了解下. Web 缓存游走于服务器和客户端之间.这个服务器可能是 ...
- delphi 面向对象实用技能教学一(递归)
本例使用类与TList相结合,用简洁的方法,实现了一个 HTML 解析与格式化功能.所用到的知识点如下:1.类的提前申明2.TList用法3.String的指针操作4.单例设计5.递归用法 编程是综合 ...
- AndroidStudio中导入SlidingMenu报错解决方案
----------------------------------------------------------------------------------------------[版权申明: ...
- N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法,且要求K<=15*N.
N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列.设计加密解密算法,且要求K<=15*N. ...
- Java通过实现Runnable接口来创建线程
创建一个线程,最简单的方法是创建一个实现Runnable接口的类. 为了实现Runnable,一个类只需要执行一个方法调用run(),声明如下: public void run() 你可以重写该方法, ...
- 优化Javascript数据遍历
问题 M是一个对象的集合,没个对象拥有唯一的字符串类型的Id N是Id的集合. 从M中过滤掉Id不在N中的对象. 假如M有50w个数据,N中可能是0~50w任意的数据. 方案1 使用数组保存Id的集合 ...
- Android Studio下多渠道打包
Android Studio下实现多渠道打包 直接上步骤 步骤 1. 清单文件添加属性(以友盟统计为例) 在application标签下添加meta-data属性 <application -- ...