SBJson 5.0.3

SBJson 5.0.3

测试已测试
语言语言 Obj-CObjective C
许可 BSD-3-Clause
发布最新发布2020 年 1 月

Stig Brautaset 维护。



SBJson 5.0.3

  • 作者
  • Stig Brautaset

SBJson 5

基于块进行 Objective-C 中的 JSON 解析和生成。

CircleCI codecov.io Project Status: Inactive - The project has reached a stable, usable state but is no longer being actively developed; support/maintenance will be provided as time allows. Carthage compatible

概述

SBJson 的首要特点是基于流的/块操作。向解析器提供一个或多个 UTF8 编码数据的块,它将调用您提供的块,按每个顶层文档或数组调用一次。或者,可选地,对于每个顶层数组中的每个顶层条目。

利用这个特性,您可以减少在慢速连接中每个下载/解析周期文件的明显延迟。在全文下载完成之前,您可以开始解析并返回解析文档的块。您还可以逐步解析大量文件,因此不必将它们全部保留在内存中。

SBJson 将以下 JSON 类型映射到 Objective-C 类型

JSON 类型 Objective-C 类型
null NSNull
字符串 NSString
数组 NSMutableArray
对象 NSMutableDictionary
-[NSNumber numberWithBool: YES]
-[NSNumber numberWithBool: NO]
数字 NSNumber
  • 布尔值往返处理适当,尽管 Objective-C 没有专门的布尔值类。
  • 整数使用 long longunsigned long long,如果它们适合,以避免舍入错误。对于所有其他数字,我们使用 double 类型,涉及所有潜在舍入错误。

“平面”基于块解析

首先定义一个简单的块和一个错误处理器。(这些只是最小示例。你应该努力做些更好的、符合你应用需求的事情!)

SBJson5ValueBlock block = ^(id v, BOOL *stop) {
    BOOL isArray = [v isKindOfClass:[NSArray class]];
    NSLog(@"Found: %@", isArray ? @"Array" : @"Object");
};

SBJson5ErrorBlock eh = ^(NSError* err) {
    NSLog(@"OOPS: %@", err);
    exit(1);
};

然后创建一个解析器并向其中添加数据

id parser = [SBJson5Parser parserWithBlock:block
                              errorHandler:eh];

id data = [@"[true," dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data]; // returns SBJson5ParserWaitingForData

// block is not called yet...

// ok, now we add another value and close the array

data = [@"false]" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data]; // returns SBJson5ParserComplete

// the above -parse: method calls your block before returning.

好吧!现在让我们看看一些稍微有趣一些的内容。

处理多个文档

这适用于类似Twitter的Feed,每行提供一个JSON文档。以下是解析多个连续JSON文档的示例,其中你的块会为每个文档调用一次

id parser = [SBJson5Parser multiRootParserWithBlock:block
                                       errorHandler:eh];

// Note that this input contains multiple top-level JSON documents
id data = [@"[]{}" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data];
[parser parse:data];

上面的示例将打印

Found: Array
Found: Object
Found: Array
Found: Object

展开一个巨大的顶层数组

通常你无法控制解析的输入,所以不能使用multiRootParser。但是,并非全都是坏事:如果你正在解析一个长长的数组,可以通过使用unwrapRootArrayParser达到相同的效果

id parser = [SBJson5Parser unwrapRootArrayParserWithBlock:block
                                             errorHandler:eh];

// Note that this input contains A SINGLE top-level document
id data = [@"[[],{},[],{}]" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data];

其他功能

  • 为了安全起见,所有输入都有一个最大嵌套级别。默认为32,但可配置。
  • 编写器可以对字典键进行排序,从而输出在写入时保持一致。
  • 编写器可以创建可读性强的输出,带有换行符和缩进。
  • 可以在同一个应用程序中并行安装SBJson v3、v4和v5。(这是因为所有类和公共符号都包含主要版本号。)

注意事项

基于流的解析意味着你将失去在使用整个输入返回答案之前的解析器所拥有的某些正确性验证。理论上,文档的一部分可能返回为“看似正确的”,但随后在文档的较晚部分遇到错误。在考虑是否适合您的应用程序时,请注意这一点。

美国模糊兔

我对 sbjson 二进制文件进行了超过 24 小时的 AFL 运行,没有发现崩溃。(我无法重现手动解析它们时报告的挂起。)

                       american fuzzy lop 2.35b (sbjson)

┌─ process timing ─────────────────────────────────────┬─ overall results ─────┐
│        run time : 1 days, 0 hrs, 45 min, 26 sec      │  cycles done : 2      │
│   last new path : 0 days, 0 hrs, 5 min, 24 sec       │  total paths : 555    │
│ last uniq crash : none seen yet                      │ uniq crashes : 0      │
│  last uniq hang : 0 days, 2 hrs, 11 min, 43 sec      │   uniq hangs : 19     │
├─ cycle progress ────────────────────┬─ map coverage ─┴───────────────────────┤
│  now processing : 250* (45.05%)     │    map density : 0.70% / 1.77%         │
│ paths timed out : 0 (0.00%)         │ count coverage : 3.40 bits/tuple       │
├─ stage progress ────────────────────┼─ findings in depth ────────────────────┤
│  now trying : auto extras (over)    │ favored paths : 99 (17.84%)            │
│ stage execs : 603/35.6k (1.70%)     │  new edges on : 116 (20.90%)           │
│ total execs : 20.4M                 │ total crashes : 0 (0 unique)           │
│  exec speed : 481.9/sec             │   total hangs : 44 (19 unique)         │
├─ fuzzing strategy yields ───────────┴───────────────┬─ path geometry ────────┤
│   bit flips : 320/900k, 58/900k, 5/899k             │    levels : 8          │
│  byte flips : 0/112k, 4/112k, 3/112k                │   pending : 385        │
│ arithmetics : 66/6.24M, 0/412k, 0/35                │  pend fav : 1          │
│  known ints : 5/544k, 0/3.08M, 0/4.93M              │ own finds : 554        │
│  dictionary : 0/0, 0/0, 29/1.83M                    │  imported : n/a        │
│       havoc : 64/300k, 0/0                          │ stability : 100.00%    │
│        trim : 45.19%/56.5k, 0.00%                   ├────────────────────────┘
^C────────────────────────────────────────────────────┘             [cpu: 74%]

+++ Testing aborted by user +++
[+] We're done here. Have a nice day!

API 文档

有关更多详细信息,请参阅API 文档

安装

CocoaPods

使用 SBJson 的首选方法是通过 CocoaPods。在您的 Podfile 中使用

pod 'SBJson', '~> 5.0.0'

Carthage

Semantic JSON(SBJson)与Carthage兼容。请遵循iOS入门指南

github "SBJson/SBJson" == 5.0.2

打包源代码

不再推荐的一个备选方案是将所有源文件(“Classes”文件夹的内容)复制到您自己的Xcode项目中。

示例

支持

关于向后兼容性的哲学

SBJson实行语义版本控制,这意味着我们不会在主要版本中破坏API。如果需要向后不兼容的更改,我们则发布一个新的主要版本。(这也是为什么一个不足1k行的库拥有比Emacs更多的主要版本。)

我还尝试通过允许最后三个主要版本在同一应用程序中共存而不会发生冲突,来实现从一个主要版本到另一个版本的逐步迁移。这样做的方法是在所有库的符号和文件名中放置主版本号。因此,如果v6版本发布,那么SBJson5Parser类就会变成SBJson6Parser等。

授权

BSD。详情请参阅授权