Swift - decode only interested elements

77 views Asked by At

I have a huge json data obtained from HTTP response and I need only a particular portion to be decoded as a model.

{
    "root1": {
        "items": [
            {
                ...
            },
            {
                ...
            },
            {
                ...
            },
            {
                ...
            },
            {
                ...
            }
        ]
    },
    "root2": {
        ...
    },
    "page": {
        "size": 10,
        "totalElements": 5,
        "totalPages": 1,
        "number": 0
    }
}

This is my json template and I do not want to create model for root elements. I am interested only in the items array. Any direct way to decode it?

2

There are 2 answers

2
Joakim Danielson On BEST ANSWER

You can select what to decode by using a CodingKey enum but you still need to decode from the top/root level.

struct Response: Decodable {
    let root1: Root1

    enum CodingKeys: String, CodingKey {
        case root1
    }
}

struct Root1: Decodable {
    let items: [Item]

    enum CodingKeys: String, CodingKey {
        case items
    }
}

and then the decoding could be done as

var items: [Item] = []
do {
     items = try JSONDecoder().decode(Response.self, from: data).root1.items
} catch {

}
1
Dávid Pásztor On

When creating a Decodable type, you only have to declare the properties that you want to decode from JSON. All the keys that you don't care about can be omitted. You don't even need CodingKeys for this.

Think about the properties used for decoding as a minimum set of requirements, not as a complete set of requirements. Decoding will never fail because there are keys in the JSON that you didn't specify on your Decodable model.

You do need to decode from the top level through all intermediate levels though, so you have to declare top-level objects.

Decodable models:

struct Item: Decodable {
  ...
}

struct Root1: Decodable {
  let items: [Item]
}

struct Response: Decodable {
  let root1: Root1
}

Decoding:

let response = try JSONDecoder().decode(Response.self, from: json)
let items = response.root1.items