Как разобрать json рекурсивно используя codable с swift - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь определить модель класса декодирования для декодирования этого вида json-файла: здесь короткое извлечение, чтобы понять проблему, в действительности она более вложенная.

{
    "Title" : "Root",
    "Subtitle" : "RootTree",
    "Launch" : [
        {
            "DisplayName" : "Clients",
            "Launch" : [
                {
                    "DisplayName" : "Clients Details",
                    "Launch" : [
                        {
                            "DisplayName" : "Item1",
                            "URI" : "/rest/..."
                        },
                        {
                            "DisplayName" : "Item2",
                            "URI" : "/rest/..."
                        },
                        {
                            "DisplayName" : "Item3",
                            "URI" : "/rest/..."
                        }

                    ]
                }
            ]
        }
        ]
}   

Здесь моя структура, яиспользовал класс из-за рекурсивного использования:

final class Url: Codable {
    let name : String
    let uri: String?
    let launch: [LaunchStructure]?

    enum CodingKeys: String, CodingKey {
        case name = "DisplayName"
        case uri = "URI"
        case launch = "Launch"
    }
}
final class LaunchStructure: Codable {
    let launch: [Url]

    enum CodingKeys: String, CodingKey {
        case launch = "Launch"
    }
}

В заголовке и подзаголовке я не заинтересован, поэтому я исключил его из класса. Я хотел бы получить отображаемое имя и URI из предметов. Как я уже сказал, структура более вложенная, но всегда одна и та же структура. Можно ли прочитать элементы, используя рекурсивный способ. Я должен расшифровать его следующим образом:

...
let result  = Result { try JSONDecoder().decode(LaunchStructure.self, from: data) } 

Спасибо, с наилучшими пожеланиями, Арнольд

1 Ответ

0 голосов
/ 07 октября 2019

Вам совсем не нужны два типа, достаточно одного:

struct Item: Codable {
    let name : String? // not all entries in your example has it, so it's optional
    let uri: String?
    let launch: [Item]? // same here, all leaf items doesn't have it

    enum CodingKeys: String, CodingKey {
        case name = "DisplayName"
        case uri = "URI"
        case launch = "Launch"
    }
}
...