Combine之Operator(Encoding and decoding 编解码)

791 阅读1分钟

github.com/agelessman/…

.encode.decode经常用于对网络响应数据的编码和解码,在真实开发中会经常用到,可以把他们理解为对数据的映射。

encode

image.png

encode是编码的意思,在上图中,我们把Student对象编码成Json数据。.encode()接收一个参数,该参数需要实现TopLevelEncoder协议,因为TopLevelEncoder协议实现了编码的核心方法。

在开发中,我们最常用的是JSONEncoderPropertyListEncoder。当然也可以自己实现TopLevelEncoder协议,这个不在本文的讨论范围之内。

struct Student: Codable {
    let name: String
    let age: Int
    let score: Int
}

let subject = PassthroughSubject<Student, Never>()
cancellable = subject
    .encode(encoder: JSONEncoder())
    .map {
        String(data: $0, encoding: .utf8)
    }
    .sink(receiveCompletion: {
        print($0)
    }, receiveValue: { someValue in
        print(someValue ?? "")
    })

subject.send(Student(name: "张三", age: 20, score: 90))

打印结果:

{"name":"张三","age":20,"score":90}

decode

image.png

decode刚好是encode的逆向过程,通常情况下,把Json数据解析成一个具体的对象。.decode()接收一个参数,该参数需要实现TopLevelEncoder协议,因为TopLevelEncoder协议实现了编码的核心方法。

在开发中,我们最常用的是JSONEncoderPropertyListEncoder。当然也可以自己实现TopLevelEncoder协议,这个不在本文的讨论范围之内。

其代码和encode代码非常相似:

struct Student: Codable {
    let name: String
    let age: Int
    let score: Int
}

let subject = PassthroughSubject<Data, Never>()
cancellable = subject
    .decode(type: Student.self,
            decoder: JSONDecoder())
    .sink(receiveCompletion: {
        print($0)
    }, receiveValue: { someValue in
        print(someValue)
    })

subject.send(Data("{\"name\":\"张三\",\"age\":20,\"score\":90}".utf8))

打印结果:

Student(name: "张三", age: 20, score: 90)