so I have a struct that I need to send the data as the payload to a POST request. But I also need to append more data to that payload along with the struct. How do I merge the data together.
struct Series: Codable, Hashable, Identifiable {
let id: Int
let title: String
let overview: String
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
static func == (lhs: Series, rhs: Series) -> Bool {
lhs.id == rhs.id
}
enum CodingKeys: String, CodingKey {
case id
case title
case overview
}
}
let series = Series(...args)
// Encode
let jsonData = try? JSONEncoder().encode(series)
let apendedData: //Not sure what to type this as = [
"foo": true,
"bar": {
"baz": true
}
]
/* Expected payload
{
"id: 1,
"title": "Random title",
"overview": "This is an overview",
"foo": true,
"bar": {
"baz": true
}
}
*/
It's not obvious what you are after. E.g. adding additional data right after JSON is one thing, adding it as another field in JSON is another, MIME - yet another, adding extra parameters as part of the query string or headers - yet another again.
It's not necessary to use JSONSerialization here unless you're combining arbitrary values together. To stay within the Encodable world you can simply use composition with custom encoding. I'd recommend staying structured and generic if you can.
struct CommonValues<AdditionalValues: Encodable>: Encodable {
let bar: Baz
let additionalValues: AdditionalValues
enum CodingKeys: CodingKey { case bar }
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(bar, forKey: .bar)
try additionalValues.encode(to: encoder)
}
}
That will encode bar and additionalValues at the same level in the resulting object.
You could also just define container values with arbitrary arity (at least until the compiler gives up):
struct EncodeMany<First, Second, Third>: Encodable where First: Encodable, Second: Encodable, Third: Encodable {
let first: First
let second: Second
let third: Third
func encode(to encoder: Encoder) throws {
try first.encode(to: encoder)
try second.encode(to: encoder)
try third.encode(to: encoder)
}
}
well, Merging multiple encodables in this way may cause crashes because multiple different container types from the same encoder. see Aggregating two Encodable’s