Milk 用于您的 Swift 序列化 - 在 Swift 中实现序列化的简单接口和运算符集合。
Milk 提供的接口允许您序列化 class
和 struct
类型,属性可以是不可变的 (let
) 或可变的 (var
),无需使用隐式解包 !
。
Milk 意在格式无关,提供能够与 JSON 一样序列化到二进制的接口。为了文档的目的,此处的示例将主要涉及将数据序列化为和反序列化为 JSON。
注意:Milk 需要 Swift 2.0,因为它使用协议扩展现有常见方法的默认实现。
struct Person {
let name: String
let age: Int
let height: Float
init(age: Int, name: String, height: height) {
self.name = name
self.age = age
self.height = height
}
}
extension Person: Serializable {
private init?(name: String?, age: Int?, height: Float?) {
if let name = name, age = age, height = height {
self.name = name
self.age = age
self.height = height
} else {
return nil
}
}
func serialize(serializer: Serializer) {
serializer["name"] <- name
serializer["age"] <- age
serializer["height"] <- height
}
static func deserialize(deserializer: Serializer) -> Person? {
return Person(name: <-deserializer["name"],
age: <-deserializer["age"],
height: <-deserializer["height"])
}
}
let jsonSerializer: Serializer = JSONSerializer()
let person: Person = Person(name: "Matt", age: 12, height: 71.2)
person.serialize(jsonSerializer)
if let data = try jsonSerializer.toData() {
...
}
SwiftyJSONMilk 是一个 JSON 序列化器实现,底层使用 SwiftyJSON。这既可以按原样使用,也可以作为其他序列化器的参考实现。
如上例所示,Milk 为便利性提供了几个前缀和后缀运算符。这些提供了使用 Serializer
的更简洁方式。
您不需要输入
let age: Int? = 12
serializer.serializeOptional(age, forKeyPath: "age")
而是可以使用
serializer["age"] <- age
好看,吧?
对于反序列化
let age: Int? = deserializer.deserializeValueForKeyPath("age")
//vs
let age: Int? = <-deserializer["age"]
这非常适合与可选构造函数一起使用
extension Person: Serializable {
private init?(name: String?, age: Int?, height: Float?) {
if let name = name, age = age, height = height {
self.age = age
self.name = name
self.height = height
} else {
return nil
}
}
static func deserialize(deserializer: Serializer) -> Patient? {
return Person(name: <-deserializer["name"],
age: <-deserializer["age"],
height: <-deserializer["height"])
}
}
任何实现 Serializable
的模型都应该使用 keyPath 方法来序列化所需的每个属性。
大多数 JSON API 端点要么返回一个项目的数组,要么返回一个根级别字典。`Serializer` 提供了一些无 keypath 的方法来序列化和反序列化这些根级别项目。
// Serialize an array as the root object
func serialize<T: Serializable>(values: [T])
func deserializeValue<T: Serializable>() -> [T]?
// shorthand
let friends: [Person]
let serializer: Serializer
serializer <- friends
let friends: [Person]?
let deserializer: Serializer
friends <-deserializer
// Serialize a dictionary as the root object
func serialize<T: Serializable>(value: T)
func deserializeValue<T: Serializable>() -> T?
// shorthand
let person: Person
let serializer: Serializer
serializer <- person
let person: Person?
let deserializer: Serializer
person <-deserializer
Serializable
任何符合 Serializable
的 class
、struct
或 enum
都可以通过 `Serializer` 进行序列化。
您可以嵌套 Serializable
对象。以下是一个嵌套必需的 Person
值 owner 以及非必需的 previous owners 的示例,它是作为可选的 Person
对象集合持有的。
struct Car {
let manufacturer: String
let model: String
let owner: Person
let previousOwners: [Person]?
}
extension Car: Serializable {
private init?(manufacturer: String?, model: Int?, owner: Person?, previousOwners: [Person]?) {
if let manufacturer = manufacturer, model = model, owner = owner {
self.manufacturer = manufacturer
self.model = model
self.owner = owner
self.previousOwners = previousOwners
} else {
return nil
}
}
static func deserialize(deserializer: Serializer) -> Car? {
return Car(manufacturer: <-deserializer["manufacturer"],
model: <-deserializer["model"],
owner: <-deserializer["owner"],
previousOwners: <-deserializer["previousOwners"])
}
}
Serializer
Serializer
协议要求你实现一系列方法来序列化和反序列化基本的数据类型 Int
、Float
、Double
、String
和 Bool
。
// MARK: Serialization
func serialize(value: Bool, forKeyPath keyPath: String)
func serialize(value: Int16, forKeyPath keyPath: String)
func serialize(value: Int32, forKeyPath keyPath: String)
func serialize(value: Int64, forKeyPath keyPath: String)
func serialize(value: Int, forKeyPath keyPath: String)
func serialize(value: UInt16, forKeyPath keyPath: String)
func serialize(value: UInt32, forKeyPath keyPath: String)
func serialize(value: UInt64, forKeyPath keyPath: String)
func serialize(value: UInt, forKeyPath keyPath: String)
func serialize(value: Float, forKeyPath keyPath: String)
func serialize(value: Double, forKeyPath keyPath: String)
func serialize(value: String, forKeyPath keyPath: String)
// MARK: Deserialization
func deserializeValueForKeyPath(keyPath: String) -> Bool?
func deserializeValueForKeyPath(keyPath: String) -> Int16?
func deserializeValueForKeyPath(keyPath: String) -> Int32?
func deserializeValueForKeyPath(keyPath: String) -> Int64?
func deserializeValueForKeyPath(keyPath: String) -> Int?
func deserializeValueForKeyPath(keyPath: String) -> UInt16?
func deserializeValueForKeyPath(keyPath: String) -> UInt32?
func deserializeValueForKeyPath(keyPath: String) -> UInt64?
func deserializeValueForKeyPath(keyPath: String) -> UInt?
func deserializeValueForKeyPath(keyPath: String) -> Float?
func deserializeValueForKeyPath(keyPath: String) -> Double?
func deserializeValueForKeyPath(keyPath: String) -> String?
你还必须提供与符合 Serializable
协议的任何类型 T
一起工作的实现。
func serialize<T: Serializable>(value: T)
func serialize<T: Serializable>(value: T, forKeyPath keyPath: String)
func deserializeValue<T: Serializable>() -> T?
func deserializeValueForKeyPath<T: Serializable>(keyPath: String) -> T?
以及提供与上述类型同质化集合一起工作的方法。
func serialize<T: Serializable>(values: [T])
func serialize<T: Serializable>(values: [T], forKeyPath keyPath: String)
func serialize(values: [Bool], forKeyPath keyPath: String)
func serialize(values: [Int16], forKeyPath keyPath: String)
func serialize(values: [Int32], forKeyPath keyPath: String)
func serialize(values: [Int64], forKeyPath keyPath: String)
func serialize(values: [Int], forKeyPath keyPath: String)
func serialize(values: [UInt16], forKeyPath keyPath: String)
func serialize(values: [UInt32], forKeyPath keyPath: String)
func serialize(values: [UInt64], forKeyPath keyPath: String)
func serialize(values: [UInt], forKeyPath keyPath: String)
func serialize(values: [Float], forKeyPath keyPath: String)
func serialize(values: [Double], forKeyPath keyPath: String)
func serialize(values: [String], forKeyPath keyPath: String)
func deserializeValue<T: Serializable>() -> [T]?
func deserializeValueForKeyPath<T: Serializable>(keyPath: String) -> [T]?
func deserializeValueForKeyPath(keyPath: String) -> [Bool]?
func deserializeValueForKeyPath(keyPath: String) -> [Int16]?
func deserializeValueForKeyPath(keyPath: String) -> [Int32]?
func deserializeValueForKeyPath(keyPath: String) -> [Int64]?
func deserializeValueForKeyPath(keyPath: String) -> [Int]?
func deserializeValueForKeyPath(keyPath: String) -> [UInt16]?
func deserializeValueForKeyPath(keyPath: String) -> [UInt32]?
func deserializeValueForKeyPath(keyPath: String) -> [UInt64]?
func deserializeValueForKeyPath(keyPath: String) -> [UInt]?
func deserializeValueForKeyPath(keyPath: String) -> [Float]?
func deserializeValueForKeyPath(keyPath: String) -> [Double]?
func deserializeValueForKeyPath(keyPath: String) -> [String]?