Neat. Thanks for the JSONDecoder example. There are some errors in the code you posted. I think it should be something like:
if let jsonData = json.data(using: .utf8) {
if let timeSeries = try? JSONDecoder().decode(TimeSeries.self, from: jsonData) {
print(timeSeries.parameters)
}
else {
print("timeSeries was nil")
}
}
else {
print("Found non UTF-8 characters.")
}
But here is my question: the op’s json is actually more complicated than your structs indicate because timeSeries itself is a key in a larger dictionary. Doesn’t that mean you have to define yet another struct with timeSeries being a property of that struct? If so, then things seem to get just as unwieldy as with JSONSerialization in Swift 3 when you have deeply nested json. Also, I can imagine a top level json dictionary with 1,000 keys. Would the struct also need 1,000 properties?
Given all that, is SwiftyJSON a better solution? Uhg. I’m having no luck getting a JSONDecoder example to work on the op’s JSON.
Success! You can actually pick out the keys that you are interested in, so if the json has 1,000 keys you don’t need to define a struct with 1,000 properties.
struct Parameters: Codable {
var name: String
var levelType: String
var level: Int
var unit: String
var values: [Int]
}
struct TimeSeries: Codable {
var parameters: [Parameters] //Pick out only one key from the timeSeries dict.
}
struct Outer: Codable {
var timeSeries: [TimeSeries] //Pick out only one key from the top level dict.
}
Inside some method:
let json = """
{
"approvedTime": "2018-02-08T18:02:25Z",
"referenceTime": "2018-02-08T18:00:00Z",
"geometry": {
"type": "Point",
"coordinates": [
[
16.178786,
58.573639
]
]
},
"timeSeries": [
{
"validTime": "2018-02-08T19:00:00Z",
"parameters": [
{
"name": "spp",
"levelType": "hl",
"level": 0,
"unit": "percent",
"values": [-9]
},
{
"name": "pcat",
"levelType": "hl",
"level": 0,
"unit": "category",
"values": [0]
}
]
}
]
}
"""
if let jsonData = json.data(using: .utf8) {
if let outer = try? JSONDecoder().decode(Outer.self, from: jsonData) {
print(outer.timeSeries[0].parameters[0].name)
}
else {
print("outer was nil: either from invalid json or structs not matching the json")
}
}
else {
print("Found non UTF-8 characters in json string.")
}
You can do the same thing with SwiftyJSON, and you don’t have to go through all the trouble of defining the three structs. I do see how JSONDecode would be valuable in the right situation.