Outlaw 1.1.0

Outlaw 1.1.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2017年5月
SwiftSwift版本3.0
SPM支持SPM

Brian Mullen维护。



Outlaw 1.1.0

Outlaw

在Swift中,我们都会处理JSON、plist以及各种形式的[String: Any]。Outlaw以声明性和类型安全的方式提供了处理这些数据的各种方式。Outlaw将帮助您使用面向协议编程™的力量来编写声明性、性能良好且错误处理的代码。

使用方法

要使用Outlaw从[String: Any]中提取值,就像下面这样:

let name: String = try json.value(for: "name")
let url: URL = try json.value(for: "user.website") // extract from nested objects!

转换为模型

通常,我们希望从一个可提取的对象(比如[String: Any])将其反序列化为我们本地模型之一——例如,我们可能希望用一些JSON初始化我们的本地模型之一。

struct User: Deserializable {
    var id: Int
    var name: String
    var email: String

    init(object: Extractable) throws {
        id = try object.value(for: "id")
        name = try object.value(for: "name")
        email = try object.value(for: "email")
    }
}

现在,只需提供简单的初始化器,您就可以直接从[String: Any]提取出您的模型

let users: [User] = try json.value(for: "users")

很简单!感谢面向协议编程™!

序列化模型

我们已经看到了如何将我们的[String: Any]转换到我们本地的模型中,但反过来怎么办呢?

extension User: Serializable {
    func serialized() -> [String: Any] {
        return {
            "id": "id",
            "name" : name,
            "email": email
        }
    }
}

现在,您可能会想“但我不可以用反射来这么做吗?”您当然可以。如果您喜欢这么做,有一些其他优秀的框架可供您使用。但Outlaw认为反射可能会引导我们走向痛苦的世界。Outlaw生活在一个所见即所得™的世界里,您可以轻松地适应蛇形、驼峰或其他任何 Backend 开发者偏好的命名规范。Outlaw代码是显式的和声明性的。但不要光听Outlaw的说法,请阅读下面的文章在官方Swift博客上。

错误处理

你不在乎错误吗?使用可选数据类型。

let users: [User]? = json.value(for: "users")

否则,用do-catch包围您的代码,当出错时,您可以获得所有详细资料。

do {
    let users: [User] = try json.value(for: "users")
}
catch {
    print(error)
}

添加您的自定义值

Outlaw默认支持提取原生的Swift类型,如StringInt等,以及URLDate和符合Deserializable的任何内容,以及所有这些数据类型的数组或字典。

然而,Outlaw 并不仅仅是让你陷入绝境!添加你自己的 Outlaw 值类型就像通过扩展你的类型使用 Value 一样简单。

extension CGPoint: Value {
    public static func value(from object: Any) throws -> CGPoint {
        guard let properties = object as? [String: CGFloat] else {
            throw OutlawError.typeMismatch(expected: [String: CGFloat].self, actual: type(of: object))
        }
        let x: CGFloat = properties["x"] ?? 0
        let y: CGFloat = properties["y"] ?? 0

        return CGPoint(x: x, y: y)
    }
}

只需简单实现 value(from:),Outlaw 就允许你立即执行此操作

let point: CGPoint = try json.value(for: "point")

面向协议编程™ 再次发挥作用!

中间值

不喜欢 Outlaw 实现的默认值提取?有不同的日期格式?没问题!在提取值时只需要一个转换函数即可。

let formatter = DateFormatter()
formatter.timeZone = TimeZone(abbreviation: "GMT")
formatter.dateFormat = "MM/dd/yyyy"

let date: Date? = json.value(for: "date", with: { (dateString: String) -> Date? in
    return formatter.date(from: dateString)
})

我们也可以利用 Swift 的能力,将以上代码缩短为

let date: Date? = json.value(for: "date", with: formatter.date)

性能

Outlaw 基于与 Marshal 相同的底层代码,并且具有相同的高性能。你应始终以怀疑的态度看待基准测试,但无论如何,最好还是看一下这些基准测试 [链接]。不幸的是,JSONShootout 项目的构建方式使得 Outlaw 无法添加,因为与 Marshal 存在方法冲突。

目标

Outlaw 是由 Marshal 的主要贡献者之一创建的。然而,Marshal 被设计成一个需要扩展以提供额外功能的简化框架。而 Outlaw 被设计成一个功能更丰富的框架,可以“开箱即用”地处理更多数据提取场景。