关于可编码:如何在 Swift 4 中使用 JSONEncoder 对字典进行编码

How to encode Dictionary with JSONEncoder in Swift 4

我想用 JSONEncoder 将 Dictionary 编码为 json。
它看起来像一个请求,接收一个字典作为参数并将其编码为 json 作为 http 正文。
代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let dict = ["name":"abcde"]

protocol Request {
    var params: [String: Encodable] { get set }
    func encode< T >(_ value: T) throws -> Data where T : Encodable
}

extension Request {
    func encode< T >(_ value: T) throws -> Data where T : Encodable {
        return try JSONEncoder().encode(value)
    }

    var body: Data? {
        if let encoded = try? self.encode(self.params) {
            return encoded
        }
        return nil
    }
}

struct BaseRequest: Request {
    var params: [String : Encodable]
}

let req = BaseRequest(params: dict)
let body = req.body

但是这段代码出现错误

Fatal error: Dictionary does not conform to Encodable because Encodable does not conform to itself. You must use a concrete type to encode or decode.

我怎样才能使它可编码?


你必须按如下方式引入类型擦除:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
struct AnyEncodable: Encodable {

    let value: Encodable
    init(value: Encodable) {
        self.value = value
    }

    func encode(to encoder: Encoder) throws {
        try value.encode(to: encoder)
    }

}

struct Model: Encodable {

    var params: [String: AnyEncodable]

}

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let json = try! encoder.encode(
    Model(
        params: [
           "hello" : AnyEncodable.init(value:"world")
        ]
    ).params
)
print(String(data: json, encoding: .utf8))


如果你想定义你的结构符合Codable,你可以这样做:

1
2
3
4
5
6
7
8
struct Model: Codable {
    var param1: String
    var param2: Int
}

let model = Model(param1:"test", param2: 0)
let encoded = try? JSONEncoder().encode(model)
let decoded = try? JSONDecoder().decode(Model.self, from: encoded!)

如果您设置 params: [String: Any],它实际上不会起作用,因为编码器/解码器不知道如何编码/解码 Any,但他们可以为原始类型做到这一点。

如果您需要更多帮助,您应该阅读更多关于新的 Codable 协议的信息。我推荐这个:https://hackernoon.com/everything-about-codable-in-swift-4-97d0e18a2999