iOS开发技术部落iOS DevelopmentiOS点点滴滴

iOS基于CocoaLumberjack的日志工具

2018-01-19  本文已影响42人  uniapp

使用Xcode编辑器进行iOS开发,其高效的便捷性和友好的开发体验,无可非议。我毫不怀疑:如果对所有程序猿开发的编辑器做一个排名的话,Xcode肯定能排上前几名。但是不得不说Xcode中的一个缺点是:打印日志不能分级。Android开发中可以对日志分为verbose,debug,error,warning,info等级别,这样能很方便的在编辑器中对日志信息进行过滤,定位问题更加方便。所以,「Ernesto Rivera」大神就开发出了CocoaLumberjack,可以方便的对日志进行分级。

CocoaLumberjack (VS) NSLog 具有效率高、功能强大、便于拓展的诸多优点。CocoaLumberjack的基本使用,github上面写的很详细。可以通过Cocoapods或者将文件直接嵌入工程的方式来使用,可以同时实现在Xcode日志栏、App沙盒目录、iPhone线程三个地方输出日志。

结合实际工程,最好的使用方式是:在CocoaLumberjack基础上,封装成自己的Log日志方式。这样做既可以保持工程编码风格的一致性,同时让工程代码与第三方依赖库隔离,防止以后依赖库没人维护时,顺利地替换成其他库。比如我们在iOS开发中,常常基于AFNetworking封装自己工程的网络请求。

封装CocoaLumberjack很方便,因为CocoaLumberjack本身已经预留了拓展的接口DDDispatchQueueLogFormatter。新建类ZDLogFormatter继承自DDDispatchQueueLogFormatter,重写- (NSString *)formatLogMessage:(DDLogMessage *)logMessage方法定义日志的具体格式。

@interface ZDLogFormatter : DDDispatchQueueLogFormatter

@end

@implementation ZDLogFormatter

//日志具体格式
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage
{

    NSString *logLevel = nil;
    switch (logMessage.flag)
    {
            
        case DDLogFlagError:
            logLevel = @"[ERROR] > ";
            break;
        case DDLogFlagWarning:
            logLevel = @"[WARN]  > ";
            break;
        case DDLogFlagInfo:
            logLevel = @"[INFO]  > ";
            break;
        case DDLogFlagDebug:
            logLevel = @"[DEBUG] > ";
            break;
        case DDLogFlagVerbose:
            logLevel = @"[VBOSE] > ";
            break;
        default:
            logLevel = @"[VBOSE] > ";
            break;
    }
    
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    NSInteger interval = [zone secondsFromGMTForDate:logMessage.timestamp];
    NSDate *localeDate = [logMessage.timestamp dateByAddingTimeInterval:interval];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss:SSS"];
    NSString *formatStr = [NSString stringWithFormat:@"%@ %@[%@ %@][line %@][thread:%@]:\n%@",
                           [dateFormatter stringFromDate:localeDate],
                           logLevel,
                           logMessage.fileName,
                           logMessage.function,
                           @(logMessage.line),
                           [self queueThreadLabelForLogMessage:logMessage],
                           logMessage.message];
    return formatStr;
}
@end

定义自己的日志工具类ZDLog,继承至NSObject。

//.h文件
#import "CocoaLumberjack.h"
#import <Foundation/Foundation.h>

#ifdef LOG_LEVEL_DEF
#undef LOG_LEVEL_DEF
#define LOG_LEVEL_DEF ZDLog_logLevel
#endif

#ifdef LOG_ASYNC_ENABLED
#undef LOG_ASYNC_ENABLED
#ifdef DEBUG
#define LOG_ASYNC_ENABLED NO
#else
#define LOG_ASYNC_ENABLED YES
#endif
#endif

typedef NS_ENUM(NSUInteger, ZDLogLevel)
{
    ZDLogLevelOff = DDLogLevelOff,
    ZDLogLevelError = DDLogLevelError,
    ZDLogLevelWarning = DDLogLevelWarning,
    ZDLogLevelInfo = DDLogLevelInfo,
    ZDLogLevelDebug = DDLogLevelDebug,
    ZDLogLevelVerbose = DDLogLevelVerbose,
    ZDLogLevelAll = DDLogLevelAll
};
extern int ZDLog_logLevel;

#define ZDLogError(frmt, ...)   DDLogError(frmt, ##__VA_ARGS__)
#define ZDLogWarn(frmt, ...)    DDLogWarn(frmt, ##__VA_ARGS__)
#define ZDLogInfo(frmt, ...)    DDLogInfo(frmt, ##__VA_ARGS__)
#define ZDLogDebug(frmt, ...)   DDLogDebug(frmt, ##__VA_ARGS__)
#define ZDLogVerbose(frmt, ...) DDLogVerbose(frmt, ##__VA_ARGS__)

@interface ZDLog : NSObject
/**
 *
 *  设置日志级别,必须设置,否则不打开日志
 *
 *  @param logLevel 级别,见枚举.
 */
+ (void)setLevel:(ZDLogLevel)logLevel;
@end

//.m文件
#import "ZDLog.h"
#import "DDDispatchQueueLogFormatter.h"
#ifdef DEBUG
int ZDLog_logLevel = ZDLogLevelVerbose;
#else
int ZDLog_logLevel = ZDLogLevelWarning;
#endif

@implementation ZDLog

+ (void)setLevel:(ZDLogLevel)logLevel
{
    ZDLog_logLevel = (int)logLevel;
    [DDLog removeAllLoggers];
    [self addTTYLoggerWithLevel:(ZDLogLevel) logLevel];
    [self addFileLoggerWithLevel:(ZDLogLevel) logLevel];
    [self addASLLoggerWithLevel:(ZDLogLevel) logLevel];
}
//添加日志到iPhone后台线程
+ (void)addASLLoggerWithLevel:(ZDLogLevel)logLevel
{
    DDASLLogger *logger = [DDASLLogger sharedInstance];
    logger.logFormatter = [[ZDLogFormatter alloc] init];
    [DDLog addLogger:logger withLevel:(DDLogLevel) logLevel];
}
//添加日志到Xcode打印区
+ (void)addTTYLoggerWithLevel:(ZDLogLevel)logLevel
{
    DDTTYLogger *ttyLogger = [DDTTYLogger sharedInstance];
    ttyLogger.logFormatter = [[ZDLogFormatter alloc] init];
    [DDLog addLogger:ttyLogger withLevel:(DDLogLevel) logLevel];
}
//添加日志到App沙河目录
+ (void)addFileLoggerWithLevel:(ZDLogLevel)logLevel
{
    DDFileLogger *fileLogger = [DDFileLogger new];
    fileLogger.logFileManager.maximumNumberOfLogFiles = 10;
    fileLogger.logFormatter = [[ZDLogFormatter alloc] init];
    [DDLog addLogger:fileLogger withLevel:(DDLogLevel) logLevel];
}
@end

使用时,首先调用ZDLog的类方法setLevel定义需要显示的日志等级。这样在需要打印日志的地方,设置引入ZDLog的头文件,然后就可以调用ZDLog来打印日志了:

ZDLogError(@"ZDLogError");
ZDLogWarn(@"ZDLogWarn");
ZDLogInfo(@"ZDLogInfo");
ZDLogDebug(@"ZDLogDebug");
ZDLogVerbose(@"ZDLogVerbose");

快快试一下吧~

关注和喜欢都是对我的鼓励和支持~
上一篇下一篇

猜你喜欢

热点阅读