JSON 数据解析

前言

  • Objective-C

    1
    NS_CLASS_AVAILABLE(10_7, 5_0) @interface NSJSONSerialization : NSObject
  • Swift

    1
    @available(iOS 5.0, *) public class NSJSONSerialization : NSObject

1、JSON 数据

  • JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于 ECMAScript 的一个子集。JSON 采用完全独立于语言的文本格式,但是也使用了类似于 C 语言家族的习惯(包括 C、C++、 C#、Java、JavaScript、Perl、Python 等)。这些特性使 JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。

1.1 JSON 语法规则

  • JSON 语法是 JavaScript 对象表示语法的子集。
    • 数据在键值对中
    • 数据由逗号分隔
    • 花括号保存对象
    • 方括号保存数组

1.2 JSON 基础结构

  • JSON 结构有两种,JSON 简单说就是 javascript 中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构。

    • 1、对象:对象在 JSON 中表示为 “{}” 括起来的内容,数据结构为 {key:value, key:value, …} 的键值对的结构,在面向对象的语言中,key 为对象的属性,value 为对应的属性值,所以很容易理解,取值方法为 对象[key] 获取属性值,这个属性值的类型可以是数字、字符串、数组、对象几种。
    • 2、数组:数组在 JSON 中表示为 “[]” 括起来的内容,数据结构为 [“java”, “javascript”, “vb”, …],取值方式和所有语言中一样,使用索引获取。字段值的类型可以是 数字、字符串、数组、对象几种。

1.3 JSON 名称/值对

  • JSON 数据的书写格式是:名称/值对。
  • 名称/值对组合中的名称写在前面(在双引号中),值对写在后面(同样在双引号中),中间用冒号隔开:”firstName”:”John”

1.4 JSON 值

  • JSON 值可以是:
    • 数字(整数或浮点数)
    • 字符串(在双引号中)
    • 逻辑值(true 或 false)
    • 数组(在方括号中)
    • 对象(在花括号中)
    • null

1.5 JSON 基础示例

  • 简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。这个字符串看起来有点儿古怪,但是 JavaScript 很容易解释它,而且 JSON 可以表示比 “名称/值对” 更复杂的结构。例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表。

  • 1、表示名称/值对:

    • 按照最简单的形式,可以用下面这样的 JSON 表示 “名称/值对”:

      1
      {"firstName":"Brett"}
    • 这个示例非常基本,而且实际上比等效的纯文本 “名称/值对” 占用更多的空间:

      1
      firstName=Brett
    • 但是,当将多个 “名称/值对” 串在一起时,JSON 就会体现出它的价值了。首先,可以创建包含多个 “名称/值对” 的记录,比如:

      1
      {"firstName":"Brett", "lastName":"McLaughlin", "email":"aaaa"}
    • 从语法方面来看,这与 “名称/值对” 相比并没有很大的优势,但是在这种情况下 JSON 更容易使用,而且可读性更好。例如,它明确地表示以上三个值都是同一记录的一部分;花括号使这些值有了某种联系。

  • 2、表示数组

    • 当需要表示一组值时,JSON 不但能够提高可读性,而且可以减少复杂性。例如,假设您希望表示一个人名列表。在 XML 中,需要许多开始标记和结束标记;如果使用典型的 “名称/值对”(就像在本系列前面文章中看到的那种名 “名称/值对”),那么必须建立一种专有的数据格式,或者将键名称修改为 person1-firstName 这样的形式。如果使用 JSON,就只需将多个带花括号的记录分组在一起:

      1
      2
      3
      4
      5
      6
      7
      {
      "people":[
      {"firstName":"Brett", "lastName":"McLaughlin", "email":"aaaa"},
      {"firstName":"Jason", "lastName":"Hunter", "email":"bbbb"},
      {"firstName":"Elliotte", "lastName":"Harold", "email":"cccc"}
      ]
      }
    • 这不难理解。在这个示例中,只有一个名为 people 的变量,值是包含三个条目的数组,每个条目是一个人的记录,其中包含名、姓和电子邮件地址。上面的示例演示如何用括号将记录组合成一个值。当然,可以使用相同的语法表示多个值(每个值包含多个记录):

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      {
      "programmers":[
      {"firstName": "Brett", "lastName": "McLaughlin", "email": "aaaa"},
      {"firstName": "Jason", "lastName": "Hunter", "email": "bbbb"},
      {"firstName": "Elliotte", "lastName": "Harold", "email": "cccc"}
      ],

      "authors":[
      {"firstName": "Isaac", "lastName": "Asimov", "genre": "sciencefiction"},
      {"firstName": "Tad", "lastName": "Williams", "genre": "fantasy"},
      {"firstName": "Frank", "lastName": "Peretti", "genre": "christianfiction"
      }
      ],

      "musicians":[
      {"firstName": "Eric", "lastName": "Clapton", "instrument": "guitar"},
      {"firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano"
      }
      ]
      }
    • 这里最值得注意的是,能够表示多个值,每个值进而包含多个值。但是还应该注意,在不同的主条目(programmers、authors 和 musicians)之间,记录中实际的 “名称/值对” 可以不一样。JSON 是完全动态的,允许在 JSON 结构的中间改变表示数据的方式。在处理 JSON 格式的数据时,没有需要遵守的预定义的约束。所以,在同样的数据结构中,可以改变表示数据的方式,甚至可以以不同方式表示同一事物。

1.6 JSON 具体形式

  • 1、对象是一个无序的 “名称/值对” 集合

    • 1)一个对象以 “{” 左括号开始,“}” 右括号结束。
    • 2)每个 “名称” 后跟一个 “:” 冒号;
    • 3)“名称/值对” 之间使用 “,” 逗号分隔。

    • 例子:表示人的一个对象:

      1
      2
      3
      4
      {
      "姓名":"大憨",
      "年龄":24
      }
  • 2、数组是值(value)的有序集合

    • 1)一个数组以 “[” 左中括号开始,“]” 右中括号结束。
    • 2)值之间使用 “,” 逗号分隔。

    • 例子:一组学生

      1
      2
      3
      4
      5
      {
      "学生": [{"姓名":"小明","年龄":23}, {"姓名":"大憨","年龄":24}]
      }

      说明:此 Json 对象包括了一个学生数组,而学生数组中的值又是两个 Json 对象。
  • 3、值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)。这些结构可以嵌套。

  • 4、字符串(string)是由双引号包围的任意数量 Unicode 字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。 字符串(string)与 C 或者 Java 的字符串非常相似。

  • 5、数值(number)也与 C 或者 Java 的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

1.7 JSON 和 XML 的比较

  • 可读性

    • JSON 和 XML 的可读性可谓不相上下,一边是简易的语法,一边是规范的标签形式,很难分出胜负。
  • 可扩展性

    • XML 天生有很好的扩展性,JSON 当然也有,没有什么是 XML 可以扩展而 JSON 却不能扩展的。不过 JSON 在 Javascript 主场作战,可以存储 Javascript 复合对象,有着 XML 不可比拟的优势。
  • 编码难度

    • XML 有丰富的编码工具,比如 Dom4j、JDom 等,JSON 也有提供的工具。无工具的情况下,相信熟练的开发人员一样能很快的写出想要的 XML 文档和 JSON 字符串,不过,XML 文档要多很多结构上的字符。
  • 解码难度

    • XML 的解析方式有两种:

      • 一是通过文档模型解析,也就是通过父标签索引出一组标记。例如:xmlData.getElementsByTagName(“tagName”),但是这样是要在预先知道文档结构的情况下使用,无法进行通用的封装。
      • 另外一种方法是遍历节点(document 以及 childNodes)。这个可以通过递归来实现,不过解析出来的数据仍旧是形式各异,往往也不能满足预先的要求。
      • 凡是这样可扩展的结构数据解析起来一定都很困难。
    • JSON 也同样如此:

      • 如果预先知道 JSON 结构的情况下,使用 JSON进 行数据传递简直是太美妙了,可以写出很实用美观可读性强的代码。如果你是纯粹的前台开发人员,一定会非常喜欢 JSON。但是如果你是一个应用开发人员,就不是那么喜欢了,毕竟 XML 才是真正的结构化标记语言,用于进行数据传递。
      • 而如果不知道 JSON 的结构而去解析 JSON 的话,那简直是噩梦。费时费力不说,代码也会变得冗余拖沓,得到的结果也不尽人意。但是这样也不影响众多前台开发人员选择 JSON。因为 json.js 中的 toJSONString() 就可以看到 JSON 的字符串结构。当然不是使用这个字符串,这样仍旧是噩梦。常用 JSON 的人看到这个字符串之后,就对 JSON 的结构很明了了,就更容易的操作 JSON。
    • 以上是在 Javascript 中仅对于数据传递的 XML 与 JSON 的解析。在 Javascript 地盘内,JSON 毕竟是主场作战,其优势当然要远远优越于 XML。如果 JSON 中存储 Javascript 复合对象,而且不知道其结构的话,我相信很多程序员也一样是哭着解析 JSON 的。

    • 除了上述之外,JSON 和 XML 还有另外一个很大的区别在于有效数据率。JSON 作为数据包格式传输的时候具有更高的效率,这是因为 JSON 不像 XML 那样需要有严格的闭合标签,这就让有效数据量与总数据包比大大提升,从而减少同等数据流量的情况下,网络的传输压力 。

1.8 iOS JSON 解析第三方框架

  • JSON 解析常用的第三方框架有:JSONKit、SBJson、TouchJSON,其性从左到右依次降低。

  • JSONKit 已经在 2012 年停止更新,官方说 JSONKit 比苹果原生的 NSJSONSerialization 解析速度快,实测其实苹果原生的 NSJSONSerialization 解析速度更快。

  • 由于 NSJSONSerialization 在 iOS 5.0 之后才出现,NSJSONSerialization 适用于 iOS 5.0+ 版本的 iOS 开发。JSONKit 框架适用于 iOS 4.0 及以前版本的 iOS 开发。

2、系统方式 JSON 数据解析

  • Objective-C

    • 解析 json 数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      /*
      反序列化:将从服务器接收到的二进制数据转换成 NSDictionary / NSArray 的过程,简化程序开发,便于后续的字典转模型。
      数据必须符合 json 格式,用来接收的容器必须和 json 的最外层保持一致。

      NSJSONReadingMutableContainers = (1UL << 0), // 容器可变,NSMutableDictionary 或 NSMutableArray。
      NSJSONReadingMutableLeaves = (1UL << 1), // 叶子可变,返回的 JSON 对象中字符串的值为 NSMutableString。
      NSJSONReadingAllowFragments = (1UL << 2) // 允许 JSON 字符串最外层既不是 NSArray 也不是 NSDictionary,
      但必须是有效的 JSON 片段

      反序列化中的可变不可变,实际用处不大,后续紧接着就是字典转模型。因此输入 0 效率最好。如果今后看到 ** 类型的参数,
      又不想获取对应的内容,传递 NULL 即可。传入 nil 不会抱错。
      */

      // 从本地文件中读取数据
      NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JsonDataFile" ofType:@"txt"]];

      // 解析 json 数据
      id result = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:NULL];
    • 生成 json 数据

      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
      /*
      序列化:将字典或者数组发送给服务器之前,转换成二进制数据,方便网络传输。

      生成 json 数据的对象必须满足以下条件:
      对象最外层必须是 NSArray 或者 NSDictionary。
      容器内的所有数据必须是 NSString, NSNumber, NSArray, NSDictionary, 或者 NSNull 类型。
      字典的所有 key 都是 NSString 格式。
      NSNumber 不能是 NaN(非数值) 或者 infinity(无限大)。

      NSJSONWritingOptions:
      NSJSONWritingPrettyPrinted = (1UL << 0) 漂亮的格式打印

      使用 0 时,生成的数据格式如下,将 JSON 数据发送给服务器时可以使用该种格式。

      {"age":8,"score":99,"add":"beijing","name":"xiaoxin"}

      使用 1 时,生成的数据格式如下,将 JSON 数据保存到本地时可以使用该种格式。

      {
      "age" : 8,
      "score" : 99,
      "add" : "beijing",
      "name" : "xiaoxin"
      }
      */

      // Foundation object
      NSDictionary *dicitionary = @{@"name":@"xiaoxin", @"age":@8, @"score":@99, @"add":@"beijing"};

      // 判断 Foundation 对象是否可以生成 json 数据
      BOOL isValid = [NSJSONSerialization isValidJSONObject:dicitionary];

      // 生成 json 数据
      NSData *jData = [NSJSONSerialization dataWithJSONObject:dicitionary options:0 error:NULL];
  • Swift

    • 解析 json 数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      /*
      反序列化:将从服务器接收到的二进制数据转换成 NSDictionary / NSArray 的过程,简化程序开发,便于后续的字典转模型。
      数据必须符合 json 格式,用来接收的容器必须和 json 的最外层保持一致。

      MutableContainers // 容器可变,NSMutableDictionary 或 NSMutableArray。
      MutableLeaves // 叶子可变,返回的 JSON 对象中字符串的值为 NSMutableString。
      AllowFragments // 允许 JSON 字符串最外层既不是 NSArray 也不是 NSDictionary,但必须是有效的 JSON 片段

      反序列化中的可变不可变,实际用处不大,后续紧接着就是字典转模型。因此输入 0 效率最好。如果今后看到 ** 类型的参数,
      又不想获取对应的内容,传递 NULL 即可。传入 nil 不会抱错。
      */

      // 解析 json 数据
      let jsonDataDic: AnyObject? = try? NSJSONSerialization.JSONObjectWithData(jsonData!, options: .MutableContainers)
    • 生成 json 数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      /*
      序列化:将字典或者数组发送给服务器之前,转换成二进制数据,方便网络传输。

      生成 json 数据的对象必须满足以下条件:

      对象最外层必须是 NSArray 或者 NSDictionary。
      容器内的所有数据必须是 NSString, NSNumber, NSArray, NSDictionary, 或者 NSNull 类型。
      字典的所有 key 都是 NSString 格式。
      NSNumber 不能是 NaN(非数值) 或者 infinity(无限大)。
      */

      // Foundation object
      let dicitionary: [String:AnyObject] = ["name":"xiaoxin", "age":8, "score":99, "add":"beijing"]

      // 判断 Foundation 对象是否可以生成 json 数据
      let isValid: Bool = NSJSONSerialization.isValidJSONObject(dicitionary)

      // 生成 json 数据
      let jData: NSData? = try? NSJSONSerialization.dataWithJSONObject(dicitionary, options: .PrettyPrinted)

3、JSONKit 方式 JSON 数据解析

3.1 添加 JSONKit

  • GitHub 网址

  • JSONKit 使用 MRC

  • Objective-C

    1
    2
    3
    4
    5
    6
    7
    8
    // 添加第三方库文件
    JSONKit

    // 在 TARGETS -> Build Phases -> Compile Sources -> ...in .../JSONKit 后添加
    -fno-objc-arc

    // 包含头文件
    #import "JSONKit.h"
  • Swift

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 添加第三方库文件
    JSONKit

    // 在 TARGETS -> Build Phases -> Compile Sources -> ...in .../JSONKit 后添加
    -fno-objc-arc

    // 创建名为 “项目名-Bridging-Header.h” 的桥接头文件,如:
    SwiftJSON-Bridging-Header.h

    // 在 TARGETS -> Build Setting -> Swift Compiler - Code generation -> Objective-C Bridging Header 中
    // 添加 “项目名/项目名-Bridging-Header.h” 路径,如:
    SwiftJSON/SwiftJSON-Bridging-Header.h

    // 在创建的桥接头文件中包含头文件
    #import "JSONKit.h"

3.2 JSONKit 数据解析

  • Objective-C

    • JSONDecoder 方式解析

      1
      2
      3
      4
      5
      6
      // 从本地文件中读取数据
      NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JsonDataFile" ofType:@"txt"]];

      id result = [[JSONDecoder decoder] objectWithData:jsonData];

      NSLog(@"%@ %@", result, [result class]);
    • JSONString 解析

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      // 单层 JSONString 解析
      /*
      如果 json 是 “单层” 的,即 value 都是字符串、数字,可以使用 objectFromJSONString
      */

      // 单层 JSONString 数据
      NSString *jsonStr1 = @"{\"a\":123, \"b\":\"abc\"}";

      // 返回可变结果使用 mutableObjectFromJSONString 方法
      NSDictionary *jsonStrDic1 = [jsonStr1 objectFromJSONString];

      // 嵌套 JSONString 解析
      /*
      如果 json 有嵌套,即 value 里有 array、object,如果再使用 objectFromJSONString,程序可能会报错,
      测试结果表明:使用由网络或得到的 php/json_encode 生成的 json 时会报错,但使用 NSString 定义的 json 字符串时,
      解析成功,最好使用 objectFromJSONStringWithParseOptions:
      */

      // 嵌套 JSONString 数据
      NSString *jsonStr2 = @"{\"a\":123, \"b\":\"abc\", \"c\":[456, \"hello\"], \"d\":{\"name\":\"张三\", \"age\":\"32\"}}";

      // 返回可变结果使用 mutableObjectFromJSONStringWithParseOptions 方法
      NSDictionary *jsonStrDic2 = [jsonStr2 objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
    • JSONData 解析

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      // 单层 JSONData 解析

      NSData *jsonData1 = [@"{\"a\":123, \"b\":\"abc\"}" dataUsingEncoding:NSUTF8StringEncoding];

      // 返回可变结果使用 mutableObjectFromJSONData 方法
      NSDictionary *jsonDataDic1 = [jsonData1 objectFromJSONData];

      // 嵌套 JSONData 解析

      // 从本地文件中读取数据
      NSData *jsonData2 = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JsonDataFile" ofType:@"txt"]];

      // 返回可变结果使用 mutableObjectFromJSONStringWithParseOptions 方法
      NSDictionary *jsonDataDic2 = [jsonData2 objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode];
    • 生成 JSONString 数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      // NSString -> JSONString

      NSString *str1 = @"{a\":123, \"b\":\"abc\"}";

      // 默认参数为 JKSerializeOptionNone,includeQuotes 为 YES
      NSString *jsonStrFromStr1 = [str1 JSONString];

      // includeQuotes 为 NO 时,编码后的数据最外层不含引号
      NSString *jsonStrFromStr2 = [str1 JSONStringWithOptions:JKSerializeOptionNone includeQuotes:NO error:nil];

      // NSArray/NSDictionary -> JSONString

      NSDictionary *dic1 = @{@"name":@"xiaoxin", @"age":@8, @"Info":@{@"score":@99, @"add":@"beijing"}};

      // 默认参数为 JKSerializeOptionNone
      NSString *jsonStrFromDic1 = [dic1 JSONString];

      NSString *jsonStrFromDic2 = [dic1 JSONStringWithOptions:JKSerializeOptionEscapeUnicode error:nil];
    • 生成 JSONData 数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      // NSString -> JSONData

      NSString *str2 = @"{a\":123, \"b\":\"abc\"}";

      // 默认参数为 JKSerializeOptionNone,includeQuotes 为 YES
      NSData *jsonDataFromStr1 = [str2 JSONData];

      NSData *jsonDataFromStr2 = [str2 JSONDataWithOptions:JKSerializeOptionNone includeQuotes:NO error:nil];

      // NSArray/NSDictionary -> JSONData

      NSDictionary *dic2 = @{@"name":@"xiaoxin", @"age":@8, @"Info":@{@"score":@99, @"add":@"beijing"}};

      // 默认参数为 JKSerializeOptionNone
      NSData *jsonDataFromDic1 = [dic2 JSONData];

      NSData *jsonDataFromDic2 = [dic2 JSONDataWithOptions:JKSerializeOptionEscapeUnicode error:nil];
  • Swift

    • JSONDecoder 方式解析

      1
      2
      3
      4
      5
      6
      // 从本地文件中读取数据
      let jsonData: NSData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("JsonDataFile", ofType: "txt")!)!

      let result: AnyObject = JSONDecoder.decoder().objectWithData(jsonData)

      print(result);
    • JSONString 解析

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      // 单层 JSONString 解析
      /*
      如果 json 是 “单层” 的,即 value 都是字符串、数字,可以使用 objectFromJSONString
      */

      // 单层 JSONString 数据
      let jsonStr1: String = "{\"a\":123, \"b\":\"abc\"}"

      // 返回可变结果使用 mutableObjectFromJSONString 方法
      let jsonStrDic1: AnyObject = jsonStr1.objectFromJSONString()

      // 嵌套 JSONString 解析
      /*
      如果 json 有嵌套,即 value 里有 array、object,如果再使用 objectFromJSONString,程序可能会报错,
      测试结果表明:使用由网络或得到的 php/json_encode 生成的 json 时会报错,但使用NSString 定义的 json 字符串时,
      解析成功,最好使用 objectFromJSONStringWithParseOptions:
      */

      // 嵌套 JSONString 数据
      let jsonStr2: String = "{\"a\":123, \"b\":\"abc\", \"c\":[456, \"hello\"], \"d\":{\"name\":\"张三\", \"age\":\"32\"}}"

      // 返回可变结果使用 mutableObjectFromJSONStringWithParseOptions 方法
      let jsonStrDic2: AnyObject = jsonStr2.objectFromJSONStringWithParseOptions(UInt(JKParseOptionLooseUnicode))
    • JSONData 解析

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      // 单层 JSONData 解析

      let jsonData1: NSData = "{\"a\":123, \"b\":\"abc\"}".dataUsingEncoding(NSUTF8StringEncoding)!

      // 返回可变结果使用 mutableObjectFromJSONData 方法
      let jsonDataDic1: AnyObject = jsonData1.objectFromJSONData()

      // 嵌套 JSONData 解析

      // 从本地文件中读取数据
      let jsonData2: NSData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("JsonDataFile", ofType: "txt")!)!

      // 返回可变结果使用 mutableObjectFromJSONDataWithParseOptions 方法
      let jsonDataDic2: AnyObject = jsonData2.objectFromJSONDataWithParseOptions(UInt(JKParseOptionLooseUnicode))
    • 生成 JSONString 数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      // String -> JSONString

      let str1: String = "{a\":123, \"b\":\"abc\"}"

      // 默认参数为 JKSerializeOptionNone,includeQuotes 为 YES
      let jsonStrFromStr1: String = str1.JSONString()

      // includeQuotes 为 NO 时,编码后的数据最外层不含引号
      let jsonStrFromStr2: String = try! str1.JSONStringWithOptions(UInt(JKSerializeOptionNone), includeQuotes:false)

      // NSArray/NSDictionary -> JSONString

      let dic1 :NSDictionary = ["name":"xiaoxin", "age":8, "Info":["score":99, "add":"beijing"]]

      // 默认参数为 JKSerializeOptionNone
      let jsonStrFromDic1: String = dic1.JSONString()

      let jsonStrFromDic2: String = try! dic1.JSONStringWithOptions(UInt(JKSerializeOptionEscapeUnicode))
      • 生成 JSONData 数据

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        // String -> JSONData

        let str2: String = "{a\":123, \"b\":\"abc\"}"

        // 默认参数为 JKSerializeOptionNone,includeQuotes 为 YES
        let jsonDataFromStr1: NSData = str2.JSONData()

        // includeQuotes 为 NO 时,编码后的数据最外层不含引号
        let jsonDataFromStr2: NSData = try! str2.JSONDataWithOptions(UInt(JKSerializeOptionNone), includeQuotes:false)

        // NSArray/NSDictionary -> JSONData

        let dic2: NSDictionary = ["name":"xiaoxin", "age":8, "Info":["score":99, "add":"beijing"]]

        // 默认参数为 JKSerializeOptionNone
        let jsonDataFromDic1: NSData = dic2.JSONData()

        let jsonDataFromDic2: NSData = try! dic2.JSONDataWithOptions(UInt(JKSerializeOptionEscapeUnicode))

4、JSONKit 与 NSJSONSerialization 对比测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
static int largeNumber = 100 * 1000;

// JSONKit 解析

NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://192.168.88.200/demo.json"]];

NSLog(@"JSONKit start");
CFAbsoluteTime start1 = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < largeNumber; ++i) {
[[JSONDecoder decoder] objectWithData:jsonData];
}
NSLog(@"JSONKit end: %f \n", CFAbsoluteTimeGetCurrent() - start1);

// NSJSONSerialization 解析

NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://192.168.88.200/demo.json"]];

NSLog(@"NSJSONSerialization start");
CFAbsoluteTime start2 = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < largeNumber; ++i) {
[NSJSONSerialization JSONObjectWithData:jsonData options:0 error:NULL];
}
NSLog(@"NSJSONSerialization end: %f", CFAbsoluteTimeGetCurrent() - start2);
文章目录
  1. 1. 前言
  2. 2. 1、JSON 数据
    1. 2.1. 1.1 JSON 语法规则
    2. 2.2. 1.2 JSON 基础结构
    3. 2.3. 1.3 JSON 名称/值对
    4. 2.4. 1.4 JSON 值
    5. 2.5. 1.5 JSON 基础示例
    6. 2.6. 1.6 JSON 具体形式
    7. 2.7. 1.7 JSON 和 XML 的比较
    8. 2.8. 1.8 iOS JSON 解析第三方框架
  3. 3. 2、系统方式 JSON 数据解析
  4. 4. 3、JSONKit 方式 JSON 数据解析
    1. 4.1. 3.1 添加 JSONKit
    2. 4.2. 3.2 JSONKit 数据解析
  5. 5. 4、JSONKit 与 NSJSONSerialization 对比测试
隐藏目录