Xcode打印日志有时候显示的unicode,不是我们想要的中文,尤其是与后台调试接口的时候,面对乱麻麻的unicode,那是一个苦逼啊。
解决方案
为NSObject,NSString,NSDictionary,NSArray,NSSet添加分类 .h文件中
@interface debugging : NSObject
@end
@interface NSObject (DEBUGGING)
+ (void)replaceClassMethodWithClass: (Class)clazz originMethod: (SEL)originMethodSEL withMethod: (SEL)newMethodSEL;
@end
@interface NSString (DEBUGGING)
+ (NSString*) stringByReplaceUnicode:(NSString*)string;
@end
@interface NSDictionary (DEBUGING)
@end
@interface NSArray (DEBUGGING)
@end
@interface NSSet (DEBUGGING)
@end
.m文件中
@implementation NSObject (DEBUGGING)
+ (void)replaceClassMethodWithClass: (Class)clazz originMethod: (SEL)originMethodSEL withMethod: (SEL)newMethodSEL
{
Method originMethod = class_getInstanceMethod(clazz, originMethodSEL);
Method newMethod = class_getInstanceMethod(clazz, newMethodSEL);
method_exchangeImplementations(originMethod, newMethod);
}
@end
@implementation NSString (DEBUGGING)
//http://stackoverflow.com/questions/2099349/using-objective-c-cocoa-to-unescape-unicode-characters-ie-u1234?lq=1
+ (NSString*) stringByReplaceUnicode:(NSString*)string
{
// unescape quotes and backwards slash
NSString* unescapedString = [string stringByReplacingOccurrencesOfString:@"\\\"" withString:@"\""];
unescapedString = [unescapedString stringByReplacingOccurrencesOfString:@"\\\\" withString:@"\\"];
// tokenize based on unicode escape char
NSMutableString* tokenizedString = [NSMutableString string];
NSScanner* scanner = [NSScanner scannerWithString:unescapedString];
while ([scanner isAtEnd] == NO)
{
// read up to the first unicode marker
// if a string has been scanned, it's a token
// and should be appended to the tokenized string
NSString* token = @"";
[scanner scanUpToString:@"\\u" intoString:&token];
if (token != nil && token.length > 0)
{
[tokenizedString appendString:token];
continue;
}
// skip two characters to get past the marker
// check if the range of unicode characters is
// beyond the end of the string (could be malformed)
// and if it is, move the scanner to the end
// and skip this token
NSUInteger location = [scanner scanLocation];
NSInteger extra = scanner.string.length - location - 4 - 2;
if (extra < 0)
{
NSRange range = {location, -extra};
[tokenizedString appendString:[scanner.string substringWithRange:range]];
[scanner setScanLocation:location - extra];
continue;
}
// move the location pas the unicode marker
// then read in the next 4 characters
location += 2;
NSRange range = {location, 4};
token = [scanner.string substringWithRange:range];
unichar codeValue = (unichar) strtol([token UTF8String], NULL, 16);
[tokenizedString appendString:[NSString stringWithFormat:@"%C", codeValue]];
// move the scanner past the 4 characters
// then keep scanning
location += 4;
[scanner setScanLocation:location];
}
// done
return tokenizedString;
}
@end
}
@end
@implementation NSDictionary (DEBUGING)
+ (void)load
{
[self replaceClassMethodWithClass:[NSDictionary class] originMethod:@selector(description) withMethod:@selector(Exchangeddescription)];
[self replaceClassMethodWithClass:[NSDictionary class] originMethod:@selector(descriptionWithLocale:) withMethod:@selector(ExchangeddescriptionWithLocale:)];
[self replaceClassMethodWithClass:[NSDictionary class] originMethod:@selector(descriptionWithLocale:indent:) withMethod:@selector(ExchangeddescriptionWithLocale:indent:)];
}
- (NSString *)Exchangeddescription
{
NSString * description = [self Exchangeddescription];
description = [NSString stringByReplaceUnicode:description];
return description;
}
- (NSString *)ExchangeddescriptionWithLocale:(id)locale
{
NSString * description = [self ExchangeddescriptionWithLocale:locale];
description = [NSString stringByReplaceUnicode:description];
return description;
}
- (NSString *)ExchangeddescriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSString * description = [self ExchangeddescriptionWithLocale:locale indent:level];
description = [NSString stringByReplaceUnicode:description];
return description;
}
@end
@implementation NSArray (DEBUGGING)
+ (void)load
{
[self replaceClassMethodWithClass:[NSArray class] originMethod:@selector(description) withMethod:@selector(Exchangeddescription)];
[self replaceClassMethodWithClass:[NSArray class] originMethod:@selector(descriptionWithLocale:) withMethod:@selector(ExchangeddescriptionWithLocale:)];
[self replaceClassMethodWithClass:[NSArray class] originMethod:@selector(descriptionWithLocale:indent:) withMethod:@selector(ExchangeddescriptionWithLocale:indent:)];
}
- (NSString *)Exchangeddescription
{
NSString * description = [self Exchangeddescription];
description = [NSString stringByReplaceUnicode:description];
return description;
}
- (NSString *)ExchangeddescriptionWithLocale:(id)locale
{
NSString * description = [self ExchangeddescriptionWithLocale:locale];
description = [NSString stringByReplaceUnicode:description];
return description;
}
- (NSString *)ExchangeddescriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSString * description = [self ExchangeddescriptionWithLocale:locale indent:level];
description = [NSString stringByReplaceUnicode:description];
return description;
}
@end
@implementation NSSet (DEBUGGING)
+ (void)load
{
[self replaceClassMethodWithClass:[NSSet class] originMethod:@selector(description) withMethod:@selector(Exchangeddescription)];
[self replaceClassMethodWithClass:[NSSet class] originMethod:@selector(descriptionWithLocale:) withMethod:@selector(ExchangeddescriptionWithLocale:)];
}
- (NSString *)Exchangeddescription
{
NSString * description = [self Exchangeddescription];
description = [NSString stringByReplaceUnicode:description];
return description;
}
- (NSString *)ExchangeddescriptionWithLocale:(id)locale
{
NSString * description = [self ExchangeddescriptionWithLocale:locale];
description = [NSString stringByReplaceUnicode:description];
return description;
}
@end
最后
方法中用到了运行时,别忘记了:
#import <objc/runtime.h>
把该分类文件导入到项目中就OK了。 参考了文章(http://t.cn/RLJLjnx)
效果
Before:
After: