WBAFNetworkingLogger
WBAFNetworkingLogger
是 AFNetworking 3.x 的扩展,原库中已经将原来2.x中的AFNetworkActivityLogger
移除.
为方便使用,自己根据2.x中AFNetworkActivityLogger
的内容,修改为AFNetworking3.x 可用的辅助类.
WBAFNetworkingLogger
会监听
AFNetworkingTaskDidResumeNotification
AFNetworkingTaskDidCompleteNotification
然后打印出请求和响应的关键信息.
使用方法
和AFNetworking2.x中的使用方法一样:
直接在程序启动以后调用:
[[WBAFNetworkingLogger sharedLogger] startLogging];
默认情况下使用的是Info模式,可以通过下面方法设置具体模式,一般使用Debug模式较多:
[[WBAFNetworkingLogger sharedLogger] setLevel:WBLoggerLevelDebug];
License
MIT license.
//
// WBAFNetworkingLogger.h
// WBAFNetworkingLogger
//
// Created by brownfeng on 16/9/26.
// Copyright © 2016年 brownfeng. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSUInteger, WBLoggerLevel) {
WBLoggerLevelOff,
WBLoggerLevelDebug,
WBLoggerLevelInfo,
WBLoggerLevelWarn,
WBLoggerLevelError,
WBLoggerLevelFatal = WBLoggerLevelOff,
};
@interface WBAFNetworkingLogger : NSObject
/**
The level of logging detail. See "Logging Levels" for possible values. `WBLoggerLevelInfo` by default.
*/
@property (nonatomic, assign) WBLoggerLevel level;
/**
Returns the shared logger instance.
*/
+ (instancetype)sharedLogger;
/**
Start logging requests and responses.
*/
- (void)startLogging;
/**
Stop logging requests and responses.
*/
- (void)stopLogging;
@end
//
// WBAFNetworkingLogger.m
// WBAFNetworkingLogger
//
// Created by brownfeng on 16/9/26.
// Copyright © 2016年 brownfeng. All rights reserved.
//
#import "WBAFNetworkingLogger.h"
#import "AFNetworking.h"
#import <objc/runtime.h>
static NSError * WBNetworkErrorFromNotification(NSNotification *notification) {
NSError *error = nil;
if ([[notification object] isKindOfClass:[NSURLSessionTask class]]) {
error = [(NSURLSessionTask *)[notification object] error];
if (!error) {
error = notification.userInfo[AFNetworkingTaskDidCompleteErrorKey];
}
}
return error;
}
@interface WBAFNetworkingLogger()
@end
@implementation WBAFNetworkingLogger
+ (instancetype)sharedLogger {
static WBAFNetworkingLogger *_sharedLogger = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedLogger = [[self alloc] init];
});
return _sharedLogger;
}
- (id)init {
if (self = [super init]){
self.level = WBLoggerLevelInfo;
}
return self;
}
- (void)dealloc {
[self stopLogging];
}
- (void)startLogging {
[self stopLogging];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingTaskDidResumeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidCompleteNotification object:nil];
}
- (void)stopLogging {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma -mark notification
static void * WBNetworkRequestStartDate = &WBNetworkRequestStartDate;
- (void)networkRequestDidStart:(NSNotification *)notification {
NSURLSessionTask *task = notification.object;
NSURLRequest *request = task.currentRequest;
if (!request) {
return;
}
objc_setAssociatedObject(notification.object, WBNetworkRequestStartDate, [NSDate date], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
NSString *body = nil;
if ([request HTTPBody]) {
body = [[NSString alloc] initWithData:[request HTTPBody] encoding:NSUTF8StringEncoding];
}
switch (self.level) {
case WBLoggerLevelDebug:
NSLog(@"%@ '%@': %@ %@", [request HTTPMethod], [[request URL] absoluteString], [request allHTTPHeaderFields], body);
break;
case WBLoggerLevelInfo:
NSLog(@"%@ '%@'", [request HTTPMethod], [[request URL] absoluteString]);
break;
default:
break;
}
}
-(void)networkRequestDidFinish:(NSNotification *)notification{
NSURLSessionTask *task = notification.object;
NSURLRequest *request = task.currentRequest;
NSURLResponse *response = task.response;
NSError *error = WBNetworkErrorFromNotification(notification);
if (!request && !response) {
return;
}
NSUInteger responseStatusCode = 0;
NSDictionary *responseHeaderFields = nil;
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
responseStatusCode = (NSUInteger)[(NSHTTPURLResponse *)response statusCode];
responseHeaderFields = [(NSHTTPURLResponse *)response allHeaderFields];
}
id responseObject = nil;
if (notification.userInfo) {
responseObject = notification.userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey];
}
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:objc_getAssociatedObject(notification.object, WBNetworkRequestStartDate)];
if (error) {
switch (self.level) {
case WBLoggerLevelDebug:
case WBLoggerLevelInfo:
case WBLoggerLevelWarn:
case WBLoggerLevelError:
NSLog(@"[Error] %@ '%@' (%ld) [%.04f s]: %@", [request HTTPMethod], [[response URL] absoluteString], (long)responseStatusCode, elapsedTime, error);
default:
break;
}
} else {
switch (self.level) {
case WBLoggerLevelDebug:
NSLog(@"%ld '%@' [%.04f s]: %@ %@", (long)responseStatusCode, [[response URL] absoluteString], elapsedTime, responseHeaderFields, responseObject); break;
case WBLoggerLevelInfo:
NSLog(@"%ld '%@' [%.04f s]", (long)responseStatusCode, [[response URL] absoluteString], elapsedTime);
break;
default:
break;
}
}
}
@end