I'm trying to create a Codable
Struct
in Swift based on the JSON I'm receiving.
The Json I have is:
{
"data": [
{
"id": "a123b321c456xyz",
"timeUsed": 12345678,
"input": [
[
"address_1a123b321c456xyz",
{
"getSomeString": "0123456789",
"getSomeObjectArray": []
}
],
[
"address_2a123b321c456xyz",
{
"getSomeString": "0123456789",
"getSomeObjectArray": []
}
]
],
"output": [
[
"address_3a123b321c456xyz",
{
"getSomeString": "0123456789",
"getSomeObjectArray": []
}
],
[
"address_4a123b321c456xyz",
{
"getSomeString": "0123456789",
"getSomeObjectArray": []
}
]
],
"getSomeData": {
"getSomeString": "0123456789",
"getSomeObjectArray": []
}
}
]
}
The Models that I tried to use
struct RequestData: Codable {
let data: [RequestMyData]
}
struct RequestMyData: Codable {
let id: String
let timeUsed: Int
let input: [MixedData]
let output: [MixedData]
let getSomeData: GetSomeData
}
struct MixedData: Codable {
//What should I do here?
}
struct GetSomeData: Codable {
let getSomeString: String
let getSomeObjectArray: [Object]
}
So, what confuses me is this part of JSON:
[
"address_1a123b321c456xyz",
{
"getSomeString": "0123456789",
"getSomeObjectArray": []
}
],
If you need additional explanation, please comment below. Thank you in advance.
CodePudding user response:
That is some truly strange json but it can be decoded :)
First change MixedData to
struct MixedData: Codable {
let addressField: String
let someData: GetSomeData
}
and then add a custom init(from:)
to RequestMyData where we use an unkeyed container for the input
and output
arrays and when looping those arrays we create another unkeyed container to decode to the MixedData type
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
timeUsed = try container.decode(Int.self, forKey: .timeUsed)
input = try Self.decodeMixedData(try container.nestedUnkeyedContainer(forKey: .input))
output = try Self.decodeMixedData(try container.nestedUnkeyedContainer(forKey: .output))
getSomeData = try container.decode(GetSomeData.self, forKey: .getSomeData)
}
private static func decodeMixedData(_ unkeyedContainer: UnkeyedDecodingContainer) throws -> [MixedData] {
var container = unkeyedContainer
var result = [MixedData]()
while !container.isAtEnd {
var innerContainer = try container.nestedUnkeyedContainer()
let mixed = MixedData(addressField: try innerContainer.decode(String.self),
someData: try innerContainer.decode(GetSomeData.self))
result.append(mixed)
}
return result
}
Note that the property getSomeData is not an array.