1 JSON文档结构
1.1 简介
JSON(javaScript Object Notation)是存储和交换文本信息的语法,类似 XML。JSON 比 XML 更小、更快,更易解析,是一种轻量级的数据交换格式。所谓轻量级是指与XML文档结构相比描述相同的数据所需的字符个数要少。
简单的说JSON由两种数据类型组成:数组和词典。
1.2 语法
JSON 语法是 JavaScript 语法的子集,但对于IOS开发来说,可以不需要太多了解JavaScript语法。
1) JSON 语法规则
-
数据在名称/值对中
-
数据由逗号分隔
-
花括号保存对象(无序容器)
-
方括号保存数组(有序容器)
2) JSON 名称/值对
名称/值对相当是IOS中的词典,即是映射表,但是JSON中的"名称"必须是由字符串表示。 名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值:
3) JSON 值
JSON 值可以是:
-
数字(整数或浮点数)
-
字符串(在双引号中)
-
逻辑值(true 或 false)
-
数组(在方括号中)
-
对象(在花括号中)
-
null
![](https://i-blog.csdnimg.cn/blog_migrate/8fbd76a7f6b8d7ed758c594c1346436b.gif)
图 1
4) JSON 对象
JSON 对象在花括号中书写,对象可以包含多个"名称/值"对,即对象是一个无序的"名称/值"对集合。
![](https://i-blog.csdnimg.cn/blog_migrate/9e91d326f6f1600551d63491f9c7f243.gif)
图 2
5) JSON 数组
JSON 数组在方括号中书写,数组可包含多个对象,即数组是值的有序集合。
![](https://i-blog.csdnimg.cn/blog_migrate/a2407fc8b29cb0c5661433efdb208b39.gif)
图 3
" employees ": [
{ " firstName ": " John " , " lastName ": " Doe " },
{ " firstName ": " Anna " , " lastName ": " Smith " },
{ " firstName ": " Peter " , " lastName ": " Jones " }
]
}
在上面的例子中,对象 "employees" 是包含三个对象的数组。每个对象代表一条关于某人(有姓和名)的记录。
2 JSON数据解码
2.1 IOS解码技术
目前有如下的几种解码技术,性能是从低到高排序,
-
JBjson:比较老的第三方框架;
-
TouchJSON:也是老的第三方框架;
-
YAJL:也是比较老,但性能较高;
-
JSONKit:比较优秀的JSON框架,解码速度快;
-
NSJSONSerialization:它是IOS5之后Apple提供的官方API,是目前最优秀的JSON编码/解码框架。
2.2 NSJSONSerialization
在IOS中对JSON文件的解码和编码是通过NSJSONSerialization类实现的,该类的使用方式非常方便和简单。NSJSONSerialization类的设计思想是通过一个"中介对象"与JSON文件进行互相转换。
2.2.1 以NSData为中介
由于NSData对象能够直接与文件进行交互,所以就能够以NSData对象为中间转换介质,如下图所示的转换过程。
![](https://i-blog.csdnimg.cn/blog_migrate/c783dbdf1898e068c4611172c9256ad8.png)
注意:
这里的JSON对象可以是数组、词典等类型,具体看最外层"{}"内的类型。
如下所示的"Notes.json" JSON文件,
" ResultCode ": 110,
" Record ": 112
}
如下的程序是对JSON文件进行解析为字典,然后验证是否正确;接着重新将字典编码为JSON文件。
2 [super viewDidLoad];
3 // Do any additional setup after loading the view, typically from a nib.
4
5 NSString *path = [[NSBundle mainBundle] pathForResource: @" Notes " ofType: @" json "];
6
7 NSData *jsonData = [[NSData alloc] initWithContentsOfFile:path];
8 id jsonObj = [NSJSONSerialization JSONObjectWithData:jsonData options: 0 error:nil];
9
10 NSInteger id = [jsonObj objectForKey: @" ResultCode "];
11 NSLog( @" %@ ",[jsonObj objectForKey: @" ResultCode "]);
12
13 NSData *data = [NSJSONSerialization dataWithJSONObject:jsonObj options:nil error:nil];
14 [data writeToFile: @" /Users/tengfei/Desktop/s.json " atomically: true];
15 }
2.2.2 以Stream为中介
与NSData转换中介不同,通过Stream转换它是通过两种不同的对象进行。当进行JSON文件解析时,是通过NSInputStream;而当进行编码时,是通过NSOutputStream进行。
![](https://i-blog.csdnimg.cn/blog_migrate/f63f12efb17599ea4c28f9c22aa272bb.png)
如下表是两种Stream的创建方法:
类名 | 创建Stream方法 |
NSInputStream | + (instancetype)inputStreamWithData:(NSData *)data |
+ (instancetype)inputStreamWithFileAtPath:(NSString *)path | |
+ (instancetype)inputStreamWithURL:(NSURL *)url | |
- (instancetype)initWithData:(NSData *)data | |
- (instancetype)initWithFileAtPath:(NSString *)path | |
- (instancetype)initWithURL:(NSURL *)url | |
NSOutputStream | + (instancetype)outputStreamToMemory |
+ (instancetype)outputStreamToFileAtPath:(NSString *)path append:(BOOL)shouldAppend | |
+ (instancetype)outputStreamWithURL:(NSURL *)url append:(BOOL)shouldAppend | |
- (instancetype)initToMemory | |
- (instancetype)initToFileAtPath:(NSString *)path append:(BOOL)shouldAppend | |
- (instancetype)initWithURL:(NSURL *)url append:(BOOL)shouldAppend |
如下是通过Stream进行JSON文件的编码和解码的简单示例:
2 {
3 NSString *path = [[NSBundle mainBundle] pathForResource: @" Notes " ofType: @" json "]; // 获取文件的NSString路径
4
5 NSInputStream *inputStream = [[NSInputStream alloc] initWithFileAtPath:path]; // 创建Stream对象
6 [inputStream open]; // 打开Stream对象
7
8 id jsonObj = [NSJSONSerialization JSONObjectWithStream:inputStream options:NSJSONReadingMutableLeaves error:nil];
9
10 NSInteger id = [jsonObj objectForKey: @" ResultCode "];
11 NSLog( @" %@ ",[jsonObj objectForKey: @" ResultCode "]);
12
13 // 创建输出流
14 NSOutputStream *outpuStream = [[NSOutputStream alloc] initToFileAtPath: @" /Users/tengfei/Desktop/s.json " append: true];
15 [outpuStream open]; // 打开Stream对象
16 [NSJSONSerialization writeJSONObject:jsonObj toStream:outpuStream options: 0 error:nil];
17 }