NSLog 解决中文乱码并显示成JSON格式
引言:
文章的初衷很简单,是为了能够正常显示打印出字典里面的中文。因为默认情况下,直接打印字典的话,在Xcode控制台上,中文会是乱码的,需要Unicode转码才能看到中文。
# 一. 正常打印
NSDictionary *dict = @{@"name":@"张三",
@"job":@"iOS开发工程是",
@"author":@{@"nickName":@"谦言忘语",
@"blog":@"https://www.jianshu.com/u/cc2cf725ac0c",
@"work":@"iOS工程师"}
};
NSLog(@"打印出的字典:%@",dict);
打印结果:
# 二. 解决方案
利用runtime
的方法交换 来实现:
/// DEBUG模式生效
#ifdef DEBUG
#import "SQPrintJsonLog.h"
#import <objc/runtime.h>
#pragma mark - 方法交换
static inline void sq_swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) {
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
#pragma mark - --- NSObject 分类 ---
@implementation NSObject (SQJSON)
/// 将obj转换成json字符串。如果失败则返回nil.
- (NSString *)convertToJsonString {
//先判断是否能转化为JSON格式
if (![NSJSONSerialization isValidJSONObject:self]) return nil;
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:&error];
if (error || !jsonData) return nil;
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
return jsonString;
}
@end
#pragma mark - ---NSDictionary 分类 ---
@implementation NSDictionary (SQJsonLog)
/// 用此方法交换系统的 descriptionWithLocale: 方法。该方法在代码打印的时候调用。
- (NSString *)sqjsonlog_descriptionWithLocale:(id)locale{
NSString *result = [self convertToJsonString];//转换成JSON格式字符串
if (!result) return [self sqjsonlog_descriptionWithLocale:locale];//如果无法转换,就使用原先的格式
return result;
}
/// 用此方法交换系统的 descriptionWithLocale:indent:方法。功能同上。
- (NSString *)sqjsonlog_descriptionWithLocale:(id)locale indent:(NSUInteger)level {
NSString *result = [self convertToJsonString];
if (!result) return [self sqjsonlog_descriptionWithLocale:locale indent:level];
return result;
}
/// 用此方法交换系统的 debugDescription 方法。该方法在控制台使用po打印的时候调用。
- (NSString *)sqjsonlog_debugDescription{
NSString *result = [self convertToJsonString];
if (!result) return [self sqjsonlog_debugDescription];
return result;
}
/// 在load方法中完成方法交换
+ (void)load {
//方法交换
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
sq_swizzleSelector(class, @selector(descriptionWithLocale:), @selector(sqjsonlog_descriptionWithLocale:));
sq_swizzleSelector(class, @selector(descriptionWithLocale:indent:), @selector(sqjsonlog_descriptionWithLocale:indent:));
sq_swizzleSelector(class, @selector(debugDescription), @selector(sqjsonlog_debugDescription));
});
}
@end
#pragma mark - --- NSArray 分类 ---
@implementation NSArray (SQJsonLog)
/// 用此方法交换系统的 descriptionWithLocale: 方法。该方法在代码打印的时候调用。
- (NSString *)sqjsonlog_descriptionWithLocale:(id)locale{
NSString *result = [self convertToJsonString];
if (!result) return [self sqjsonlog_descriptionWithLocale:locale];
return result;
}
/// 用此方法交换系统的 descriptionWithLocale:indent:方法。功能同上。
- (NSString *)sqjsonlog_descriptionWithLocale:(id)locale indent:(NSUInteger)level {
NSString *result = [self convertToJsonString];
if (!result) return [self sqjsonlog_descriptionWithLocale:locale indent:level];
return result;
}
/// 用此方法交换系统的 debugDescription 方法。该方法在控制台使用po打印的时候调用。
- (NSString *)sqjsonlog_debugDescription{
NSString *result = [self convertToJsonString];
if (!result) return [self sqjsonlog_debugDescription];
return result;
}
+ (void)load {
//方法交换
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
sq_swizzleSelector(class, @selector(descriptionWithLocale:), @selector(sqjsonlog_descriptionWithLocale:));
sq_swizzleSelector(class, @selector(descriptionWithLocale:indent:), @selector(sqjsonlog_descriptionWithLocale:indent:));
sq_swizzleSelector(class, @selector(debugDescription), @selector(sqjsonlog_debugDescription));
});
}
@end
#endif