I have an insurmountable problem of how to encode a payload for a request to the server using JSONEncoder(). The object should look like this:
{
"filter": {
"conditions": [
{"key": "id_wbs", "values": [1293548]},
{"key": "id_object", "values": []},
{"key": "id", "values": [""]},
{"key": "period", "values": ["month"]},
{"key": "type_chart", "values": [""]},
{"key": "tzr_type", "values": ["monthly"]},
{"key": "type_of_work", "values": []},
{"key": "id_group_object", "values": []},
{"key": "report_date", "values": [],
"value_derived": {
"columns": "max_report_date",
"bo_id": 100006,
"filter": {
"conditions": [{"key": "id_wbs", "values": [1293548]}, {"key": "operation", "values": [""]}]
}
}
}]
},
}
The problem is in the “values" keys. Depending on the value of the key, they can be either an array of integers, or an array of strings, or an array of dates. Frankly, I got confused with this and am now at an impasse. I will be grateful for any help
The preliminary data model looks like this:
struct CSITableRequest: Encodable {
let filter: TableFilter
}
struct TableFilter: Encodable {
let conditions: [TableFilterConditionItem]
}
struct TableFilterConditionItem: Encodable {
let key: TableFilterConditionKey
let values: [String] //[Int]; [Date] - This is a problematic key, which can be either an Int array, a String array, or a Date array
let value_derived: TableValueDerived?
}
enum TableFilterConditionKey: String, Encodable {
case id_wbs
case id_object
case id
case period
case type_chart
case tzr_type
case type_of_work
case id_group_object
case report_date
case operation
}
struct TableValueDerived: Encodable {
let columns: String
let bo_id: Int
let filter: TableFilter
}
2
Answers
You can create an enum with associated values to represent the idea of "string array or int array or date array". Conform this type to
Encodable
by delegating the call to theencode
method of[Int]
/[String]
/[Date]
.@Sweeper’s answer is extremely flexible and may be ideal, but assuming that each key has a specific type for its values, I prefer to make the whole thing more type-safe. This can get slightly more tedious to write, but the code is not difficult.
Rather than a key and value, you would put them together into a KeyValue enum. This is the somewhat tedious part, with some code repeated over and over again, but it makes sure the types line up.
With that, you can encode TableFilterConditionItem this way:
With that, your data structure is: