您的位置:首页 > 其它

开源HYBUnicodeReadable日志显示Unicode中文

2016-03-04 18:02 204 查看


前言

开发中经常需要打印日志以查看数据是否正确,或者说查看数据的格式。但是,苹果对于我们的
NSDictionary
NSSet
NSArray
等值有中文时,打印出来的是
Unicode
编码,人类无法直接读懂,因此,笔者研究研究如何将打印出来的日志保持原有的格式化且能够将
Unicode
编码打印出来是正常人类可读懂的中文。


实现原理

苹果给我们提供了本地化的方法,对于
NSDictionary
NSSet
NSArray
都可以重写该方法来实现:


NSSet实现

对于
NSSet
实现如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

-
(NSString
*)descriptionWithLocale:(id)locale
indent:(NSUInteger)level
{

NSMutableString
*desc
=
[NSMutableString
string];

NSMutableString
*tabString
=
[[NSMutableString
alloc]
initWithCapacity:level];

for
(NSUInteger
i
=
0;
i
<
level;
++i)
{

[tabString
appendString:@"\t"];

}

NSString
*tab
=
@"\t";

if
(level
>
0)
{

tab
=
tabString;

}

[desc
appendString:@"\t{(\n"];

for
(id
obj
in
self)
{

if
([obj
isKindOfClass:[NSDictionary
class]]

||
[obj
isKindOfClass:[NSArray
class]]

||
[obj
isKindOfClass:[NSSet
class]])
{

NSString
*str
=
[((NSDictionary
*)obj)
descriptionWithLocale:locale
indent:level
+
1];

[desc
appendFormat:@"%@\t%@,\n",
tab,
str];

}
else
if
([obj
isKindOfClass:[NSString
class]])
{

[desc
appendFormat:@"%@\t\"%@\",\n",
tab,
obj];

}
else
{

[desc
appendFormat:@"%@\t%@,\n",
tab,
obj];

}

}

[desc
appendFormat:@"%@)}",
tab];

return
desc;

}

我们这里根本缩进级别来生成对应的格式化字符串,以便解决多级嵌套时格式不太美观的问题。


NSArray实现

对于
NSArray
的实现如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

-
(NSString
*)descriptionWithLocale:(id)locale
indent:(NSUInteger)level
{

NSMutableString
*desc
=
[NSMutableString
string];

NSMutableString
*tabString
=
[[NSMutableString
alloc]
initWithCapacity:level];

for
(NSUInteger
i
=
0;
i
<
level;
++i)
{

[tabString
appendString:@"\t"];

}

NSString
*tab
=
@"";

if
(level
>
0)
{

tab
=
tabString;

}

[desc
appendString:@"\t(\n"];

for
(id
obj
in
self)
{

if
([obj
isKindOfClass:[NSDictionary
class]]

||
[obj
isKindOfClass:[NSArray
class]]

||
[obj
isKindOfClass:[NSSet
class]])
{

NSString
*str
=
[((NSDictionary
*)obj)
descriptionWithLocale:locale
indent:level
+
1];

[desc
appendFormat:@"%@\t%@,\n",
tab,
str];

}
else
if
([obj
isKindOfClass:[NSString
class]])
{

[desc
appendFormat:@"%@\t\"%@\",\n",
tab,
obj];

}
else
{

[desc
appendFormat:@"%@\t%@,\n",
tab,
obj];

}

}

[desc
appendFormat:@"%@)",
tab];

return
desc;

}

同样的道理,不过笔者对于字符串值,都加上了双引号,一眼就可以看出来是字符串类型。


NSDictionary实现

对于NSDictonary的实现如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

-
(NSString
*)descriptionWithLocale:(id)locale
indent:(NSUInteger)level
{

NSMutableString
*desc
=
[NSMutableString
string];

NSMutableString
*tabString
=
[[NSMutableString
alloc]
initWithCapacity:level];

for
(NSUInteger
i
=
0;
i
<
level;
++i)
{

[tabString
appendString:@"\t"];

}

NSString
*tab
=
@"";

if
(level
>
0)
{

tab
=
tabString;

}

[desc
appendString:@"\t{\n"];

//
遍历数组,self就是当前的数组

for
(id
key
in
self.allKeys)
{

id
obj
=
[self
objectForKey:key];

if
([obj
isKindOfClass:[NSString
class]])
{

[desc
appendFormat:@"%@\t%@
= \"%@\",\n",
tab,
key,
obj];

}
else
if
([obj
isKindOfClass:[NSArray
class]]

||
[obj
isKindOfClass:[NSDictionary
class]]

||
[obj
isKindOfClass:[NSSet
class]])
{

[desc
appendFormat:@"%@\t%@
= %@,\n",
tab,
key,
[obj
descriptionWithLocale:locale
indent:level
+
1]];

}
else
{

[desc
appendFormat:@"%@\t%@
= %@,\n",
tab,
key,
obj];

}

}

[desc
appendFormat:@"%@}",
tab];

return
desc;

}

字典打印出来的格式是{}这样的结构,我们一样要考虑嵌套情况,并且根据嵌套添加对应的级别缩进。


升级版本到Version1.0

新增NSData类型自动打印出可视化内容,只要是新增类似这样的处理:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

else
if
([obj
isKindOfClass:[NSData
class]])
{

//
如果是NSData类型,尝试去解析结果,以打印出可阅读的数据

NSError
*error
=
nil;

NSObject
*result
= [NSJSONSerialization
JSONObjectWithData:obj

options:NSJSONReadingMutableContainers

error:&error];

//
解析成功

if
(error
==
nil
&&
result
!=
nil)
{

if
([result
isKindOfClass:[NSDictionary
class]]

||
[result
isKindOfClass:[NSArray
class]]

||
[result
isKindOfClass:[NSSet
class]])
{

NSString
*str
=
[((NSDictionary
*)result)
descriptionWithLocale:locale
indent:level
+
1];

[desc
appendFormat:@"%@\t%@
= %@,\n",
tab,
key,
str];

}
else
if
([obj
isKindOfClass:[NSString
class]])
{

[desc
appendFormat:@"%@\t%@
= \"%@\",\n",
tab,
key,
result];

}

}
else
{

@try
{

NSString
*str
=
[[NSString
alloc]
initWithData:obj
encoding:NSUTF8StringEncoding];

if
(str
!=
nil)
{

[desc
appendFormat:@"%@\t%@
= \"%@\",\n",
tab,
key,
str];

}
else
{

[desc
appendFormat:@"%@\t%@
= %@,\n",
tab,
key,
obj];

}

}

@catch
(NSException
*exception)
{

[desc
appendFormat:@"%@\t%@
= %@,\n",
tab,
key,
obj];

}

}

}

我们只是尝试去解析可视化数据,若解析成功则显示出来,若解析失败就原样输出。


测试

我们来测试一下效果,我们打印如下一个字典:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

NSString
*str
=
@"我是转换成data格式的字符串";

NSData
*dataString
=
[NSData
dataWithBytes:str.UTF8String
length:str.length];

NSDictionary
*dataSet
=
@{@"key":
@"字典转成data",

@"key1":
@"在set、数组、字典中嵌套"};

NSData
*dataSetItem
=
[NSJSONSerialization
dataWithJSONObject:dataSet

options:NSJSONWritingPrettyPrinted

error:nil];

NSMutableSet
*set
=
[NSMutableSet
setWithArray:@[@"可变集合",

@"字典->不可变集合->可变集合",

dataSetItem]];

NSDictionary
*dict
=
@{@"name" :
@"标哥的技术博客",

@"title"
:
@"http://www.henishuo.com",

@"count"
:
@(11),

@"dataString"
: dataString,

@"results"
:
[NSSet
setWithObjects:@"集合值1",
@"集合值2",
set
,
nil],

@"summaries"
:
@[@"sm1",

@"sm2",

@{@"keysm":
@{@"stkey":
@"字典->数组->字典->字典"}},

dataSetItem],

@"parameters"
:
@{@"key1"
:
@"value1",

@"key2":
@{@"key11"
:
@"value11",

@"key12"
:
@[@"三层",
@"字典->字典->数组"]},

@"key13":
dataSetItem},

@"hasBug":
@[@"YES",@"NO"],

@"contact"
:
@[@"关注博客地址:http://www.henishuo.com",

@"QQ群:
324400294",

@"关注微博:标哥Jacky",

@"关注GITHUB:CoderJackyHuang"]};

NSLog(@"%@",
dict);

打印效果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

2015-12-31
16:47:42.352
demo[58176:2693559]
{

hasBug
= (

"YES",

"NO",

),

dataString
=
"我是转换成",

title
=
"http://www.henishuo.com",

count
=
11,

results
=
{(

"集合值2",

"集合值1",

{(

"可变集合",

"字典->不可变集合->可变集合",

{

key
=
"字典转成data",

key1
=
"在set、数组、字典中嵌套",

},

)},

)},

summaries
=
(

"sm1",

"sm2",

{

keysm
=
{

stkey
=
"字典->数组->字典->字典",

},

},

{

key
=
"字典转成data",

key1
=
"在set、数组、字典中嵌套",

},

),

contact
=
(

"关注博客地址:http://www.henishuo.com",

"QQ群:
324400294",

"关注微博:标哥Jacky",

"关注GITHUB:CoderJackyHuang",

),

name
=
"标哥的技术博客",

parameters
= {

key1
=
"value1",

key13
=
{

key
=
"字典转成data",

key1
=
"在set、数组、字典中嵌套",

},

key2
= {

key11
=
"value11",

key12
=
(

"三层",

"字典->字典->数组",

),

},

},

}


如何使用

首先要得到源代码,安装方式有两种,一种是直接使用
Cocoapods


1

2

3

pod
'HYBUnicodeReadable',
'~> 1.0'

或者直接下载源代码https://github.com/CoderJackyHuang/HYBUnicodeReadable,放入工程中即可

温馨提示:不需要引入头文件,即可达到效果!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: