博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【iOS开发】iOS10 Log调试小工具
阅读量:6678 次
发布时间:2019-06-25

本文共 7640 字,大约阅读时间需要 25 分钟。

一个解决iOS10在发布环境下无法查看调试log的小工具

出发点

由于iOS10系统,在发布环境下(打成ipa包安装测试或者发布之后从App Store下载安装的包),使用Xcode已经无法查看我们自己打印的log。所以就做了一个小工具,查看log,便于调试。 楼主的需求是,在安装了APP之后查看log,验证程序是否正常运行。除了在调试的时候用到,在线上包出问题之后,也能通过查看log来定位问题。

效果

楼主将该工具分成了3种模式

  • 不显示log模式 这个是默认的模式。默认初始化之后是不显示任何log的。也就是说不做任何操作。
  • Xcode控制台显示log模式 这个模式只在Xcode控制台显示log。这就是我们iOS10出来之前用的模式。通过控制台查看log。但是由于iOS10的时候,真机查看log时候会冒出一大坨没用的log,然后我们自己的log又看不见(好像Xocde8.2.1可以看见,但是还是会有很多无用的log),所以在iOS10下这个模式不好用
  • 将log写入到文件并显示(悬浮窗模式) 这个模式将log显示在Xcode控制台,同时将log写入到沙盒中。我们可以通过读取沙盒的log文件来查看log。并且log文件还可以通过邮件、QQ、微信等方式发送。这个模式就是我们这个小工具主要实现的功能了。值的一说的是,这个模式我们会有一个悬浮窗,用来随时查看沙盒的log文件内容。

废话少说,上图:

  • 第一幅图就是悬浮窗模式。图中为浮窗展开时的界面。3个按钮分别对应着上面说的悬浮窗模式、Xcode控制台显示log模式、不显示log模式。
  • 第二幅图是点击在浮窗上的【预览】之后显示的界面,这些就是我们在程序中打印的log。
  • 第三幅图是点击第二幅图右上角的分享之后的界面。如果手机安装了QQ微信Facebook等软件,可以通过这些软件来分享这个log文件。

  • 默认情况下,我们的小工具什么都不做。
  • 当我们手动触发某个开关之后,悬浮窗就显示出来。并自动在沙盒创建log文件,之后就可以使用log写入功能。
  • 悬浮窗是可以一直漂浮在APP的上方的,便于我们随时点击浮窗,查看log
  • 点击悬浮窗上的【预览】按钮就可以以界面的形式显示沙盒文件的log,并且可以选择已邮件QQ微信等形式发送log文件
  • 点击悬浮窗上的【Xcode】按钮,悬浮窗会消失,并且只会在Xcode控制台显示log。不会写入到文件。
  • 点击悬浮窗上的【关闭】按钮,悬浮窗会消失,并且log不会再打印。
  • 重启APP之后,会根据之前的模式来决定是否显示浮窗和打印log。

使用

  • 项目github地址:https://github.com/shixueqian/iOS10LogDebugTool
  • 将SQLogTool文件夹中的几个文件拖到工程中
  • 在didFinishLaunchingWithOptions方法中进行初始化 代码示例:
//需要导入头文件  #import "SQLogToolManager.h"- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    [[SQLogToolManager shareManager] logIntial];    return YES;}复制代码
  • 在应用的某个界面上设置一个开关,点击这个开关就将log工具设置到悬浮窗模式(楼主设置的是在登录界面上连续点击10次就触发方法) 代码示例:
- (IBAction)onClickWriteToTextAndShowFloatWindow:(UIButton *)sender{    [SQLogToolManager shareManager].logLevel = SQLogToolManagerLevelText;}复制代码
  • 在需要打印Log的地方使用 NSLogD()来替换平常用的NSLog() 代码示例:
- (IBAction)onClickTest:(UIButton *)sender{    for (int i = 0; i < 10; ++i)    {        NSLogD(@"这里是测试。%@:%d",@"第一个参数",i);    }}复制代码

不足之处&需改进的地方

这个只是一个小工具,所以只做了几个我认为比较重要的功能。。主要缺陷:

  • 界面长得不是很好看(管他呢)
  • 不能显示系统的log。只能显示使用NSLogD()方法打印的log。也就是说,苹果的警告log无法通过这个小工具得到。(当前,这也避免了iOS10上那些恶心的无用log)
  • 无法显示崩溃log。楼主认为这个功能不是那么重要,就没做了。

项目解析

介绍下项目用到的几个类和主要的技术点

  • SQFloatWindow 悬浮窗功能类。 继承UIWindow,将windowLevel设置为UIWindowLevelAlert + 1 来使window浮窗悬浮在APP上方。
UIWindow *preKeyWindow = [UIApplication sharedApplication].keyWindow;                self.backgroundColor = [UIColor clearColor];        self.windowLevel = UIWindowLevelAlert + 1;        self.rootViewController = [UIViewController new];        [self makeKeyAndVisible];                //还回keyWindow        if (preKeyWindow) {            [preKeyWindow makeKeyWindow];        }复制代码

值得注意的是,我们的悬浮窗不需要作为keyWindow(不然会带来很多麻烦的),所以需要将keyWindow还给之前的window。

给悬浮窗加了一个主按钮和若干个子按钮,用来点击

//添加按钮[self setupButtons];//主按钮[self setupMainBtnWithName:mainBtnName];复制代码

定义一个block属性来处理子按钮的点击事件,具体的子按钮由按钮的tag来区分

/** 点击事件block */@property (nonatomic,copy) void(^clickBlocks)(NSInteger i);复制代码

浮窗还做了一些点击展开/收回,拖拽,靠边隐藏 等操作,具体请查看源代码

  • SQLog log打印和写入文件工具类。 当调用 SQLogD(...)时,会将log显示在Xcode控制台,并且将log写入到沙盒文件中。
//目前只用到了SQLogD//Debug#define SQLogD(...) [SQLog logD:[NSString stringWithFormat:__VA_ARGS__],@""];复制代码

调用logIntial初始化方法时,会在沙盒创建log.txt文件(如果已创建就清空文件内容)。

当调用SQLogD(...)打印log时,会创建一个异步的串行队列来进行打印并写入log。

+ (void)logvLevel:(SQLogLevel)level Format:(NSString *)format VaList:(va_list)args{    __block NSString *formatTmp = format;        dispatch_async(k_operationQueue, ^{//异步串行队列                if (level >= LogLevel)//只有大于当前LogLevel级别的log才会进行操作        {            formatTmp = [[SQLog SQLogFormatPrefix:level] stringByAppendingString:formatTmp];            //写入log文件的同时,在控制台打印出来            NSLog(@"%@",formatTmp);                        NSString *contentStr = [[NSString alloc] initWithFormat:formatTmp arguments:args];            NSString *contentN = [contentStr stringByAppendingString:@"\n"];            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];                        //设置为北京时间            NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:8];//直接指定时区,这里是东8区            NSInteger seconds = [timeZone secondsFromGMTForDate: [NSDate date]];            NSDate *beiJingDate = [NSDate dateWithTimeInterval: seconds sinceDate: [NSDate date]];                        //这里是最终打印出来的字符串,可以根据需要加一些参数进去            NSString *content = [NSString stringWithFormat:@"%@ %@", [dateFormatter stringFromDate:beiJingDate], contentN];                        //使用NSFileHandle来写入数据            NSFileHandle *file = [NSFileHandle fileHandleForUpdatingAtPath:logFilePath];            [file seekToEndOfFile];            [file writeData:[content dataUsingEncoding:NSUTF8StringEncoding]];            [file closeFile];                        formatTmp = nil;        }            });}复制代码
  • SQLogToolManager 本小工具的管理类。用来整合SQLog和SQFloatWindow 并处理对外的接口和使用逻辑。
#import 
#import "SQLog.h"/** log显示宏定义。 @param ... 可变参数,跟NSLog一致 */#define NSLogD(...) do{\ switch ([SQLogToolManager shareManager].logLevel) {\ case SQLogToolManagerLevelNone:{} break;\ case SQLogToolManagerLevelLog:{\ NSLog(__VA_ARGS__);} break;\ case SQLogToolManagerLevelText:{\ SQLogD(__VA_ARGS__);} break;\ default: break;}\ } while (0);typedef enum{ SQLogToolManagerLevelNone = 0, //不打印log SQLogToolManagerLevelLog = 1, //只在控制台显示log SQLogToolManagerLevelText = 2 //在控制台显示log及在本地写入log} SQLogToolManagerLevel;@interface SQLogToolManager : NSObject/** logLevel */@property (nonatomic, assign) SQLogToolManagerLevel logLevel;/** 单例 */+ (instancetype)shareManager;/** 初始化 */- (void)logIntial;@end复制代码

NSLogD(...)宏定义中,使用logLevel属性来控制log的类型。用户改变了logLevel就改变了打印的类型。

悬浮窗子按钮的点击事件,分为三个。【预览】,【Xcode】和【关闭】。

//点击事件处理        _floatWindow.clickBolcks = ^(NSInteger i){                        switch (i)            {                case 0:                {                    //显示沙盒本地log                    [weakSelf displayLocalLog];                }                    break;                case 1:                {                    //Xcode显示log                    weakSelf.logLevel = SQLogToolManagerLevelLog;                }                    break;                case 2:                {                    //隐藏log                    weakSelf.logLevel = SQLogToolManagerLevelNone;                }                    break;                default:                    break;            }                    };复制代码

其中,【Xcode】【关闭】只是设置了logLevel,而【预览】使用了iOS提供的预览和分享的类UIDocumentInteractionController

//显示沙盒本地log- (void)displayLocalLog{    if (![SQLog getLogFilePath])    {        return;    }        //由文件路径初始化UIDocumentInteractionController    UIDocumentInteractionController *documentInteractionController  = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:[SQLog getLogFilePath]]];    self.documentInteractionController  = documentInteractionController ;    documentInteractionController.delegate = self;    //    //显示分享文档界面//    [documentInteractionController  presentOptionsMenuFromRect:[UIScreen mainScreen].bounds inView:[UIApplication sharedApplication].keyWindow.rootViewController.view animated:YES];        //直接显示预览界面    [documentInteractionController  presentPreviewAnimated:YES];}#pragma mark - UIDocumentInteractionControllerDelegate//在哪个控制器显示预览界面-(UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller{    return [UIApplication sharedApplication].keyWindow.rootViewController;}复制代码

参考

  • :一个不错的log小工具
  • :这是一个iOS上的悬浮窗
  • :https://github.com/shixueqian/iOS10LogDebugTool

谦言万语

蓝天白云,嫩草明湖,小屋人家,大雁南飞……

转载地址:http://wogxo.baihongyu.com/

你可能感兴趣的文章
Opencv3.1.0 & Win10/Win7 64位 contrib编译
查看>>
MPMoviePlayerController播放远程视频存在问题
查看>>
一个已经存在的CCSprite怎么替换新的图片
查看>>
更加安全的存取账户密码(SDK)
查看>>
NSNotificationCenter 的详细说明
查看>>
List/Vector
查看>>
黄聪:FFmpeg 使用指南
查看>>
能否不同udp socket绑定到同一IP地址和port
查看>>
C#:CodeSmith根据数据库中的表创建C#数据模型Model + 因为没有钱买正版,所以附加自己写的小代码...
查看>>
乐视4.14硬件免费日de用户体验
查看>>
ASP.NET Core MVC/WebAPi如何构建路由?
查看>>
数据库巡检脚本
查看>>
有选择的复制对象,即根据客户端传值来复制对象属性值
查看>>
随机输入一个数字,判断这个数字是不是5的倍数
查看>>
es6+最佳入门实践(3)
查看>>
神经风格转换Neural Style Transfer a review
查看>>
linux/python 常用控制台打印颜色
查看>>
做个CMS吧(一)-站点基本设置
查看>>
ios 根据颜色生成图片,十六进制颜色。
查看>>
C — 对C语言的认识
查看>>