Pasing remote JSON response
The json syntax is wrong. At a minimum you need to wrap it in {}'s and remove the trailing comma.
Sorry, here completed
{
"data": [
[
0000000000,
[
{
"count": 0
}
]
],
[
0000000000,
[
{
"count": 0
}
]
]
]
}
this is an small part from the array. Inside data array I couldn't parse the json. Everytime a the same issue, but not that the json is invalid. The JSONDecoder says that the data is not valid if I change another part of the dict (next to data) but never says that the part is invalid json.
I ran your JSON through a linter [1] and it detected an issue with it. Please post an example of well-formed JSON.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] My go-to tool for this is:
https://jsonlint.com
but I’m sure there are many other options.
This one should be correct, no issue with online json viewer
{
"parent": {
"data": [
[
1705536000,
[
{
"count": 0
}
]
],
[
1705622400,
[
{
"count": 0
}
]
],
[
1706572800,
[
{
"count": 0
}
]
],
[
1706659200,
[
{
"count": 0
}
]
]
]
}
}
There are two standard ways to decode JSON in Swift:
JSONSerialization
JSONDecoder
The first leaves you with an untyped object hierarchy, so you have to walk the tree to find the data you need. For example:
let rootObj = try JSONSerialization.jsonObject(with: Data(input.utf8))
Here rootObj
is of type Any
, so you’ll need a bunch of as?
conversions to parse it.
The second approach involves declaring Swift types that map on to the JSON:
struct Item: Decodable {
var count: Int
}
struct MyData: Decodable {
var n: Int
var items: [Item]
init(from decoder: any Decoder) throws {
var container = try decoder.unkeyedContainer()
self.n = try container.decode(Int.self)
self.items = try container.decode([Item].self)
}
enum CodingKeys: CodingKey {
case n
case item
}
}
struct Parent: Decodable {
var data: [MyData]
}
struct Root: Decodable {
var parent: Parent
}
let root = try JSONDecoder().decode(Root.self, from: Data(input.utf8))
print(root)
The main complication here is MyData
. The corresponding JSON is this:
[
1705536000,
[
{
"count": 0
}
]
],
Note how the outermost type is an array but the elements of that array use different types (Int
and [Item]
). That means you can’t rely on the compiler-generated Decodable
implementation, because it uses container(keyedBy:)
which assumes a dictionary. You have to implement init(from:)
yourself, using unkeyedContainer()
to access the array.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Thanks you a lot, you saved my day!! - It's working :-)