I have the following Swift code with some sample JSON that I'm trying to decode. You can drop this into a Playground to try it for yourself:
let json = """
{
"sessionState": "abc",
"methodResponses": [
[
"Mailbox/get",
{
"state": "92",
"accountId": "xyz"
},
"0"
]
]
}
"""
let data = json.data(using: .utf8)!
if let object = try? JSONDecoder().decode(JMAPResponse.self, from: data) {
print(object)
}else{
print("JMAP decode failed")
}
I had no idea how to handle the nested array, so I used quicktype.io, but what it generated still doesn't work.
Here is my root element with the nested array:
//Root
struct JMAPResponse: Codable{
var sessionState: String?
var methodResponses: [[JMAPResponseChild]]
}
Here is the enum that QuickType suggested I use to process the methodResponse node:
//Nested array wrapper
enum JMAPResponseChild: Codable{
case methodResponseClass(JMAPMethodResponse)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if let x = try? container.decode(JMAPMethodResponse.self) {
self = .methodResponseClass(x)
return
}
throw DecodingError.typeMismatch(JMAPResponseChild.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JMAPResponseChild"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .methodResponseClass(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
Here's the next level down:
//No-key data structure (Mailbox/get, {}, 0)
struct JMAPMethodResponse: Codable{
var method: String
var data: [JMAPMailboxList]
var id: String
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(method)
try container.encode(data)
try container.encode(id)
}
}
And finally, the lowest-level node:
struct JMAPMailboxList: Codable{
var state: String?
var accountId: String?
}
It still can't decode the structure successfully. Can anyone see what I'm doing wrong?
catchclause, print the actual error instead.catch { print(error) }.