牛奶 0.0.3

牛奶 0.0.3

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

Jordan Hamill 维护。



牛奶 0.0.3

  • Jordan Hamill

Milk

Milk 用于您的 Swift 序列化 - 在 Swift 中实现序列化的简单接口和运算符集合。

Milk 提供的接口允许您序列化 classstruct 类型,属性可以是不可变的 (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

任何符合 Serializableclassstructenum 都可以通过 `Serializer` 进行序列化。

您可以嵌套 Serializable 对象。以下是一个嵌套必需的 Personowner 以及非必需的 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 协议要求你实现一系列方法来序列化和反序列化基本的数据类型 IntFloatDoubleStringBool

// 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]?