iOS调试信息可视化

前言

在实际开发中,调试程序必不可少,Xcode模拟器与真机调试相比,有时候会有很大区别,因此有时候我们需要在利用真机调试的时候,还能实时的打印log信息,简单的说来就是把显示在控制台中的NSLog信息实时的显示的真机设备上.

思路

首先,收集log信息并不难,下文会有代码和demo供参考.
其次,调试界面的调出应该隐蔽,防止用户调出来影响体验,只有我们程序员知道如何调出来,你可以通过三指下滑调出或者摇一摇调出调试模式,后期测试无bug之后再删除该功能即可.
最后,你调出的调试界面不应该影响你对程序的其他操作,并且该模式可以在任意时刻通过隐藏手势调出来,这就要求该调试界面必须可以挪动,可以放大缩小并且隐藏手势要写到任何地方都能响应的地方,这样就不影响你进行其他页面的操作了.

具体实现过程

对调试模式封装,继承自UIView,上代码

YYLogView.h文件

//
//  YYLogView.h
//  Log
//
//  Created by yyMae on 15/12/23.
//  Copyright (c) 2015年 yyMae. All rights reserved.
//

#import 

@interface YYLogView : UIView
//直接初始化 添加到目标父视图即可使用
@end

YYLogView.m文件

//
//  YYLogView.m
//  Log
//
//  Created by yyMae on 15/12/23.
//  Copyright (c) 2015年 yyMae. All rights reserved.
//  调试信息可视化(NSLog信息实时显示,可缩放,可挪动)

#import "YYLogView.h"

@interface YYLogView ()
@property (nonatomic ,strong) UIView *keyView;
@property (nonatomic ,strong) UITextView *logView;
@property (nonatomic ,strong) UIButton *whiteSpotBtn;

@end
@implementation YYLogView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addSubview:self.keyView];
        
    }
    return self;
}

-(UIView *)keyView{
    if (_keyView==nil) {
        self.keyView=[[UIView alloc]initWithFrame:self.bounds];
        self.logView=[[UITextView alloc]initWithFrame:CGRectMake(25, 15, self.keyView.frame.size.width-50, self.keyView.frame.size.height-30)];
        [self.keyView addSubview:self.logView];
        self.keyView.userInteractionEnabled=YES;
        self.keyView.backgroundColor=[UIColor brownColor];
        self.logView.backgroundColor=[UIColor clearColor];
        self.logView.textColor=[UIColor whiteColor];
        self.logView.editable=NO;
        NSArray  *paths  =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
        NSString *docDir = [paths objectAtIndex:0];
        NSString *filePath = [docDir stringByAppendingPathComponent:@"dr.log"];
        NSData *data = [NSData dataWithContentsOfFile:filePath];
        NSString *result = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];
        self.logView.text=result;
        
        [self addGestureRecognizerToView:self];
        [self timerAction];
        
        //添加一个可以关闭的按钮
        UIButton *closeBtn=[UIButton buttonWithType:UIButtonTypeSystem];
        closeBtn.frame=CGRectMake(0, 5, 30, 15);
        closeBtn.titleLabel.font=[UIFont systemFontOfSize:15];
        [closeBtn setTitle:@"❌" forState:UIControlStateNormal];
        [closeBtn addTarget:self action:@selector(closeLoggerView) forControlEvents:UIControlEventTouchUpInside];
        [self.keyView addSubview:closeBtn];
    }
    return _keyView;
}

//==========缩放 移动 =================
// 添加所有的手势
- (void) addGestureRecognizerToView:(UIView *)view
{
    
    
    // 缩放手势
    UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchView:)];
    [view addGestureRecognizer:pinchGestureRecognizer];
    
    // 移动手势
    UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panView:)];
    [view addGestureRecognizer:panGestureRecognizer];
}

// 处理缩放手势
- (void) pinchView:(UIPinchGestureRecognizer *)pinchGestureRecognizer
{
    UIView *view = pinchGestureRecognizer.view;
    if (pinchGestureRecognizer.state == UIGestureRecognizerStateBegan || pinchGestureRecognizer.state == UIGestureRecognizerStateChanged) {
        view.transform = CGAffineTransformScale(view.transform, pinchGestureRecognizer.scale, pinchGestureRecognizer.scale);
        pinchGestureRecognizer.scale = 1;
    }
}

// 处理拖拉手势
- (void) panView:(UIPanGestureRecognizer *)panGestureRecognizer
{
    UIView *view = panGestureRecognizer.view;
    if (panGestureRecognizer.state == UIGestureRecognizerStateBegan || panGestureRecognizer.state == UIGestureRecognizerStateChanged) {
        CGPoint translation = [panGestureRecognizer translationInView:view.superview];
        [view setCenter:(CGPoint){view.center.x + translation.x, view.center.y + translation.y}];
        [panGestureRecognizer setTranslation:CGPointZero inView:view.superview];
    }
}

- (void)timerAction{
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(readd) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
    
}

-(void)readd{
    
    NSArray  *paths  =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString *docDir = [paths objectAtIndex:0];
    NSString *filePath = [docDir stringByAppendingPathComponent:@"dr.log"];
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    NSString *result = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];
    self.logView.text = result;
}

//关闭
-(void)closeLoggerView{
    [self removeFromSuperview];
}

@end

AppDelegate.m中收集NSLog信息,并且通过摇一摇手势调出调试界面

//
//  AppDelegate.m
//  Log
//
//  Created by yyMae on 15/12/15.
//  Copyright (c) 2015年 yyMae. All rights reserved.
//

#import "AppDelegate.h"
#import "YYLogView.h"
@interface AppDelegate ()

@property (nonatomic,strong) YYLogView *loggerView;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self saveLog];
    self.loggerView=[[YYLogView alloc]initWithFrame:CGRectMake(10, 80, self.window.frame.size.width-20, 200)];
    NSLog(@"调试信息可视化");
    NSLog(@"输出");
    return YES;
}

-(void)saveLog{
    
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *document = [path objectAtIndex:0];
    NSString *fileName = [NSString stringWithFormat:@"dr.log"];
    NSString *logPath = [document stringByAppendingPathComponent:fileName];
    
    NSFileManager *defaulManager = [NSFileManager defaultManager];
    [defaulManager removeItemAtPath:logPath error:nil];
    
    freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stdout);
    freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
    
}
////摇一摇
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{

    if (motion == UIEventSubtypeMotionShake) {

        [[[UIApplication sharedApplication]keyWindow]addSubview:self.loggerView];
        

    }
}

@end

需要学习的可以看下我写的demo

github地址:https://github.com/yyMae/Log-

你可能感兴趣的:(iOS调试信息可视化)