iOS 网络编程:JSON解析

摘要:
JSON比XML更小、更快,更易解析,是一种轻量级的数据交换格式。NSJSONSerialization类的设计思想是通过一个"中介对象"与JSON文件进行互相转换。如下所示的"Notes.json"JSON文件,{"ResultCode":110,"Record":112}如下的程序是对JSON文件进行解析为字典,然后验证是否正确;接着重新将字典编码为JSON文件。

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中的"名称"必须是由字符串表示。 名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是

"firstName":"John"

3) JSON 值

JSON 值可以是:

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在方括号中)
  • 对象(在花括号中)
  • null
iOS 网络编程:JSON解析第1张

图 1

4) JSON 对象

JSON 对象花括号中书写,对象可以包含多个"名称/值"对,即对象是一个无序的"名称/值"对集合

iOS 网络编程:JSON解析第2张

图 2

firstName":"John","lastName":"Doe"}

5) JSON 数组

JSON 数组方括号中书写,数组可包含多个对象,即数组有序集合

iOS 网络编程:JSON解析第3张

图 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对象为中间转换介质,如下图所示的转换过程。

iOS 网络编程:JSON解析第4张

注意:

这里的JSON对象可以是数组、词典等类型,具体看最外层"{}"内的类型。

如下所示的"Notes.json" JSON文件,

{
"ResultCode":110,
"Record":112
}

如下的程序是对JSON文件进行解析为字典,然后验证是否正确;接着重新将字典编码为JSON文件。

1-(void)viewDidLoad{
2[superviewDidLoad];
3//Doanyadditionalsetupafterloadingtheview,typicallyfromanib.4
5NSString*path=[[NSBundlemainBundle]pathForResource:@"Notes"ofType:@"json"];
6
7NSData*jsonData=[[NSDataalloc]initWithContentsOfFile:path];
8idjsonObj=[NSJSONSerializationJSONObjectWithData:jsonDataoptions:0error:nil];
9
10NSIntegerid=[jsonObjobjectForKey:@"ResultCode"];
11NSLog(@"%@",[jsonObjobjectForKey:@"ResultCode"]);
12
13NSData*data=[NSJSONSerializationdataWithJSONObject:jsonObjoptions:nilerror:nil];
14[datawriteToFile:@"/Users/tengfei/Desktop/s.json"atomically:true];
15}

2.2.2 以Stream为中介

与NSData转换中介不同,通过Stream转换它是通过两种不同的对象进行。当进行JSON文件解析时,是通过NSInputStream;而当进行编码时,是通过NSOutputStream进行

iOS 网络编程:JSON解析第5张

如下表是两种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文件的编码和解码的简单示例:

1-(void)testJsonWithStream
2{
3NSString*path=[[NSBundlemainBundle]pathForResource:@"Notes"ofType:@"json"];//获取文件的NSString路径4
5NSInputStream*inputStream=[[NSInputStreamalloc]initWithFileAtPath:path];//创建Stream对象6[inputStreamopen];//打开Stream对象7
8idjsonObj=[NSJSONSerializationJSONObjectWithStream:inputStreamoptions:NSJSONReadingMutableLeaveserror:nil];
9
10NSIntegerid=[jsonObjobjectForKey:@"ResultCode"];
11NSLog(@"%@",[jsonObjobjectForKey:@"ResultCode"]);
12
13//创建输出流14NSOutputStream*outpuStream=[[NSOutputStreamalloc]initToFileAtPath:@"/Users/tengfei/Desktop/s.json"append:true];
15[outpuStreamopen];//打开Stream对象16[NSJSONSerializationwriteJSONObject:jsonObjtoStream:outpuStreamoptions:0error:nil];
17}

免责声明:文章转载自《iOS 网络编程:JSON解析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇linux命令(45):diff命令Java 9 揭秘(17. Reactive Streams)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

前端工程中使用require.context实现前端工程自动化,批量导入路由表、批量导入svg图等场景,

require.context是什么 一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个api,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块 什么时候需要用到require.c...

hash表的理解

哈希表 先从数组说起 任何一个程序员,基本上对数组都不会陌生,这个最常用的数据结构,说到它的优点,最明显的就是两点: 简单易用,数组的简易操作甚至让大多数程序员依赖上了它,在资源富足的情况下,我们甚至会无意识地忽略其它更适用的数据结构而使用数组(别说你没这么干过..)。 查找的快速性,数组中查找元素可以直接通过下标进行定位,速度快。 我在刚开始写程序...

python科学计算_numpy_广播与下标

多维数组下标 多维数组的下标是用元组来实现每一个维度的,如果元组的长度比维度大则会出错,如果小,则默认元组后面补 : 表示全部访问; 如果一个下标不是元组,则先转换为元组,在转换过程中,列表和数组的转换有所不同。 一个列表会被转换成各个元素组成的元组,然后进行访问(此时如果不全为整数的话,则不会共享存储区域,因为无法通过改变步长来保持存储结构不变);如:l...

网络编程,从socket到epoll

网络编程,从socket到epoll 参考链接:https://www.bilibili.com/video/BV11Z4y157RY?p=2&spm_id_from=pageDriver socket基本知识: socket分类: socekt提供了流和数据报两种通信机制,即流socket和数据报socket。 简单的socket通信流程: 先...

第三节:Vue3向下兼容2(v-for、数组方法、v-model、计算属性、监听器)

一. 基本指令  1. v-for 数据准备 data() { return { userInfo: { name: 'ypf', age: 18, school: '北大' }, movies: ["星际穿越",...

【算法】滑动窗口三步走

滑动窗口介绍 对于大部分滑动窗口类型的题目,一般是考察字符串的匹配。比较标准的题目,会给出一个模式串B,以及一个目标串A。然后提出问题,找到A中符合对B一些限定规则的子串或者对A一些限定规则的结果,最终再将搜索出的子串完成题意中要求的组合或者其他。 比如:给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起...