我有以下 Swift 结构
struct Session: Encodable {
let sessionId: String
}
struct Person: Encodable {
let name: String
let age: Int
}
let person = Person(name: "Jan", age: 36)
let session = Session(sessionId: "xyz")
我需要编码为具有这种格式的 json 对象:
{
"name": "Jan",
"age": 36,
"sessionId": "xyz"
}
其中 Session
的所有键都合并到 Person
的键中
我考虑过使用带有自定义 Encodable
实现的容器结构,其中我使用了 SingleValueEncodingContainer
但它显然只能编码一个值
struct RequestModel: Encodable {
let session: Session
let person: Person
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(person)
// crash
try container.encode(session)
}
}
let person = Person(name: "Jan", age: 36)
let session = Session(sessionId: "xyz")
let requestModel = RequestModel(session: session, person: person)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(requestModel)
let json = String(data: data, encoding: .utf8)!
print(json)
我无法更改 json 格式,因为它是固定的网络 API。我可以将 sessionId
作为 Person
的属性,但我想避免这种情况,因为它们是不相关的模型。
另一种方法是让 RequestModel
从 Session
和 Person
中复制所有属性,如下所示,但这不是很好,因为我的真正的结构有更多的属性。
struct RequestModel: Encodable {
let sessionId: String
let name: String
let age: Int
init(session: Session, person: Person) {
sessionId = session.sessionId
name = person.name
age = person.age
}
}
最佳答案
调用每个可编码对象的encode(to:)
,而不是singleValueContainer()
。
无需定义额外的 CodingKeys
即可将多个可编码对象合并为一个可编码对象。
struct RequestModel: Encodable {
let session: Session
let person: Person
public func encode(to encoder: Encoder) throws {
try session.encode(to: encoder)
try person.encode(to: encoder)
}
}
关于swift - 在 Swift 中合并 Encodable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52984142/