Marshal
在Swift中,我们常常处理JSON、plist以及各种形式的[String: Any]
。Marshal
相信您不需要拥有关于单子或魔境的博士学位来有效地处理这些,您可以使用强大的功能实现声明式、高性能的错误处理代码,这是通过**协议导向编程™**实现的。
使用方法
使用Marshal从[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: Unmarshaling {
var id: Int
var name: String
var email: String
init(object: MarshaledObject) 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")
很简单!谢谢,协议导向编程™!
错误处理
你是那种在现场字典念诵类型的人,不在乎错误?使用 try?
给自己一个可选值。否则,加入守法的我们,将代码包裹在 do-catch
中,以便在出错时获取所有细节。
添加自己的值
默认情况下,Marshal
支持String
、Int
等原生 Swift 类型的提取,以及符合 Unmarshaling
协议的对象和上述所有类型的数组。由于日期格式众多,它不支持更复杂的类型,如 Date
。
但是,Marshal 不仅让你在穷途末路无援!添加自己的 Marshal 值类型就像扩展类型添加 ValueType
那样简单。
extension Date : ValueType {
public static func value(from object: Any) throws -> Date {
guard let dateString = object as? String else {
throw MarshalError.typeMismatch(expected: String.self, actual: type(of: object))
}
// assuming you have a Date.fromISO8601String implemented...
guard let date = Date.fromISO8601String(dateString) else {
throw MarshalError.typeMismatch(expected: "ISO8601 date string", actual: dateString)
}
return date
}
}
只需实现 value(from:)
,Marshal 就能立即这样做
let birthDate: Date = json.value(for: "user.dob")
面向协议的编程™ 再次登场!
回到 marshaled 对象
我们已经从 [String: Any]
转到了本地模型,那么反过来怎么办呢?
extension User: Marshaling {
func marshaled() -> [String: Any] {
return {
"id": id,
"name" : name,
"email": email
}
}
}
你可能正在想:“但我不能使用反射来自动做这件事吗?”可以。如果你喜欢这样做,还有一些其他优秀的框架可供选择。但 Marshal 认为镜子可以使你走向伤害的世界。Marshal 生活在一个所见即所得™ 的世界里,你可以轻松适应蛇形命名法、驼峰命名法或是后端开发者们喜欢的任何命名法。Marshal 代码是明确和声明性的。但不要只听 Marshal 的,还要阅读官方 Swift 博客上的好文章这里。
性能
当然,Marshal 不会没有一些西部最快的枪。你总是应该带着一颗开放的心去看待基准测试,但不妨花点时间去看看这些基准测试这里。
贡献者
Marshal
最初是Jason Larsen关于JSON解析的博客系列,但很快就发展成为社区项目。在此,我们特别感谢那些在某个阶段不同程度上通过想法和代码做出贡献的许多人。以下是一些按字母顺序排列的贡献者
- 巴特·怀特利
- 布莱恩·穆伦
- 德里克·哈斯韦
- 戴夫·德隆
- 杰森·拉尔斯南
- 马克·舒尔茨
- Nate Bird
- 蒂姆·沙德