Freddy_Suraj 2.1.1

Freddy_Suraj 2.1.1

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布上次发布2016年4月
SPM支持 SPM

Suraj 维护。



  • 作者:
  • Matt Mathias,John Gallagher 和 Zachary Waldowski

为什么选择 Freddy?

解析 JSON 优雅且安全可能很困难,但 Freddy 可以帮您解决这个问题。Freddy 是一个针对 Swift JSON 解析的可复用框架。它有三大主要优势。

首先,Freddy 为 Swift 中的 JSON 解析提供了一个类型安全的解决方案。这意味着编译器会帮助您发送和接收 JSON,以帮助防止运行时崩溃。

其次,Freddy 提供了一种利用 Swift 的泛型、枚举和函数式功能的惯用 JSON 解析解决方案。这一切都无需记住我们的文档来理解我们的魔法自定义操作符。Freddy 没有任何这些。如果您对用 Swift 编写代码(使用扩展、协议、初始化器等)感到舒适,那么您不仅可以理解 Freddy 的组织结构,而且还会感到舒适地使用 Freddy。

第三,Freddy 提供了在解析 JSON 时经常出现的错误的好信息。如果您使用不在的键对 JSON 对象进行索引,您将获得更有用的错误。如果您的索引超出范围,您将获得有用的错误。如果您尝试将 JSON 值转换为错误类型,您在这里也会得到一个很好的错误。

因此,Freddy 与 JSON 相比,谁赢得比赛?我们认为赢得比赛的是 Freddy。

用法

本部分描述了 Freddy 的基本用法。您可以在 Wiki 中找到更多有关解析数据、处理错误、将=<>JSON实例序列化为 NSData 的示例。您可以通过阅读文档 来查看完整的 API。

反序列化:解析原始数据

基本用法

考虑一些示例 JSON 数据

{
    "success": true,
    "people": [
        {
            "name": "Matt Mathias",
            "age": 32,
            "spouse": true
        },
        {
            "name": "Sergeant Pepper",
            "age": 25,
            "spouse": false
        }
    ],
    "jobs": [
        "teacher",
        "judge"
    ],
    "states": {
        "Georgia": [
            30301,
            30302,
            30303
        ],
        "Wisconsin": [
            53000,
            53001
        ]
    }
}

这里是一个使用 Freddy 解析此数据的快速示例

let data = getSomeData()
do {
    let json = try JSON(data: data)
    let success = try json.bool("success")
    // do something with `success`
} catch {
    // do something with the error
}

在我们加载数据后,我们创建了一个 JSON 的实例,这是该框架的主力。这使我们能够访问 JSON 数据中的值。我们进行 try 因为数据可能损坏,并且解析可能会导致错误。接下来,我们通过调用 JSON 上的 bool(_:) 方法来访问 "success" 键。在这里我们同样进行 try,因为访问 json"success" 键可能会失败——例如,如果我们传递了一个未知的关键字。此方法接收两个参数,都用于定义要寻找感兴趣的真值布尔值的 JSON 实例中的路径。如果找到了路径描述的 "success" 中的 Bool,则 bool(_:) 返回一个 Bool。如果路径不导向一个 Bool,则抛出适当的错误。

使用路径通过下标访问嵌套数据

使用 Freddy,可以通过路径访问 json 结构中更深层的元素。例如

let data = getSomeData()
do {
    let json = try JSON(data: data)
    let georgiaZipCodes = try json.array("states","Georgia")
    let firstPersonName = try json.string("people",0,"name")
} catch {
    // do something with the error
}

在代码 json.array("states","Georgia") 中,键 "states""Georgia" 描述了 json 中乔治亚州邮编的路径。Freddy 术语称这个过程为“下标”JSON。位于,例如 array(_:) 的括号之间的类型是一个由逗号分隔的键和索引列表,用于描述感兴趣的值的路径。

可以有任意数量的下标,每个下标可以是表示 JSON 中一个命名元素的 String,或者表示数组中一个元素的 Int。如果路径中存在无效内容,如不存在于 JSON 中的索引,则会抛出错误。

关于下标的更多信息

JSONDecodable: 直接反序列化模型

现在,让我们看看一个将数据解析到模型类的例子

let data = getSomeData()
do {
    let json = try JSON(data: data)
    let people = try json.array("people").map(Person.init)
    // do something with `people`
} catch {
    // do something with the error
}

在这里,我们使用 array(_:) 方法将键 "people" 的值作为数组加载。该方法类似于上面看到的 bool(_:) 方法。它使用提供给方法的路径来查找一个数组。如果路径良好,该方法将返回一个 ArrayJSON。如果路径不好,则会抛出适当的错误。

然后我们可以在那个 JSON 数组上调用 map。由于 Person 类型符合 JSONDecodable,我们可以传入 Person 类型初始化器。这个调用将一个初始化器应用到数组的每个元素上,从而生成一个 Person 实例的数组。

这看起来像 JSONDecodable

public protocol JSONDecodable {
    init(json: JSON) throws
}

这是一个相当简单的协议。它所需的所有就是,符合此协议的类型必须实现一个只接受一个 JSON 实例作为其唯一参数的初始化器。

要使所有这一切紧密相连,这给出了 Person 类型的外观

public struct Person {
    public let name: String
    public let age: Int
    public let spouse: Bool
}

extension Person: JSONDecodable {
    public init(json value: JSON) throws {
        name = try value.string("name")
        age = try value.int("age")
        spouse = try value.bool("spouse")
    }
}

Person 只是具有几个属性。它通过扩展符合 JSONDecodable。在这个扩展中,我们实现了一个 throws 初始化器,它只接受一个 JSON 实例作为其唯一参数。在实现中,我们尝试了三个函数:1) string(_:),2) int(_:),和 3) bool(_:)。这些工作方式就像您之前看到的那样。方法接收一个路径,该路径用于在传递给初始化器的 JSON 实例中查找特定类型的值。由于这些路径可能无效,或者请求的类型可能与 JSON 内的实际内容不匹配,因此这些方法可能会抛出错误。

序列化

Freddy的序列化支持以JSON.serialize()方法为中心。

基本用法

JSON枚举中,可以直接转换为NSData

let someJSON: JSON =let data: NSData = try someJSON.serialize()

JSONEncodable:序列化其他对象

虽然大部分对象都不是Freddy.JSON对象,但您可以通过将它们首先转换为Freddy.JSON,使用JSONEncodable.toJSON()方法来实现,这是JSONEncodable协议的唯一方法,然后再使用serialize()方法将Freddy.JSON转换为NSData来对它们进行序列化。

let myObject: JSONEncodable =// Object -> JSON -> NSData:
let objectAsJSON: JSON = myObject.toJSON()
let data: NSData = try objectAsJSON.serialize()

// More concisely:
let dataOneLiner = try object.toJSON().serialize()

Freddy已提供常用Swift数据类型的定义。若要使自定义数据类型可序列化,则需将它符合到JSONEncodable并实现该协议的toJSON()方法。

extension Person: JSONEncodable {
    public func toJSON() -> JSON {
        return .Dictionary([
            "name": .String(name),
            "age": .Int(age),
            "spouse": .Bool(spouse)])
    }
}

入门指南

Freddy需要iOS 7.0、Mac OS X 10.9、watchOS 2.0或tvOS 9.0。暂时不支持Linux。

iOS上的动态框架需要最低部署目标为iOS 8.0。对于目标为iOS 7的项目,请参阅“Submodules”

您有几种不同的方法可以安装Freddy。

子模块

  1. git submodule add https://github.com/bignerdranch/Freddy.git Vendor/Freddy
  2. Freddy.xcodeproj拖入您的Xcode项目。
  3. Freddy.framework添加到您的应用目标的“链接框架和库”面板中。

Cartage也可以用于检出依赖项以及维护Git子模块状态。

Swift包管理器

将它添加到您的Package.swift

import PackageDescription

let package = Package(
    name: "My Nerdy App",
    dependencies: [
        .Package(url: "https://github.com/bignerdranch/Freddy.git", majorVersion: 2),
    ]
)

iOS 7

如果要用Freddy与iOS 7配合使用,则可能需要将Freddy的源代码文件复制到您的项目中。嵌入的框架在iOS 8+中才受支持。您可以将Freddy添加为子模块(见上文),然后确保将源文件添加到项目中。

设置断点错误

在开始使用一套新的JSON时,为错误设置断点可能会有所帮助。这允许您在断点处探索JSON的结构。特别是,您很可能希望为FreddyJSON.Error设置断点,以便您可以检查出了什么问题。

以下是如何设置此类断点的方法

1) 打开断点导航器

2) 点击左下角的“+”按钮

Breakpoint navigator

3) 选择“添加Swift错误断点”

Add Error Breakpoint

现在,您拥有了一个只有在生成Swift错误时才会触发的断点。但您的程序会在任何任何Swift错误被抛出时中断运行。如果您只想在抛出FreddyJSON.Error时中断,怎么办呢?

您可以对断点进行编辑,添加一个过滤器

1) 右键单击您的新错误断点

2) 选择“编辑断点…”

Edit Breakpoint

3) 将出现一个窗口,其中有一个“类型”文本框

4) 输入JSON.Error

Error Type

基本上就是这样!现在,您拥有了一个只有当抛出类型为JSON.Error的错误时才会触发的错误断点。可以查看框架的测试用例以获取更多使用示例。Wiki还有大量非常有用的信息。