Написание модели SwiftUI для чтения из файла JSON с массивами - PullRequest
2 голосов
/ 28 октября 2019

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

JSON выглядит так:

[{
    "id": 1001,
    "first_name": "Jimmy",
    "last_name": "Simms",
    "cities": [{
            "name": "New York City",
            "towns": [{
                    "name": "Brooklyn"
                },
                {
                    "name": "Manhatten"
                }
            ]
        },
        {
            "name": "Tokyo",
            "towns": [{
                    "name": "Churo"
                },
                {
                    "name": "Riponggi"
                }
            ]
        }
    ]
}]

Что я не уверен, как это сделать, так этонапишите модель, которая позволит мне нацеливать вложенные элементы внутри массивов. Вообще говоря, мне интересно, как вы могли бы исправить модель SwiftUI для этого набора JSON.

Это было своего рода ударом в темноте:

import SwiftUI

struct MyDataModel: Identifiable {
    var id: Int
    var first_name: String
    var last_name: String
    var cities: Array<Any>
    var cities.name: String
    var cities.towns: Array<Any>
    var cities.towns.name: String
}

Но мой синтаксис длядоступ к вложенным массивам "Города", а затем второй город "Городов" только что составлен, и я могу найти ссылку на то, как получить доступ к вложенному ключу, как это? Любая помощь будет высоко ценится.

1 Ответ

1 голос
/ 28 октября 2019

В основном вы хотите создать структуры для вложенных компонентов. У MyDataModel есть и массив городов, поэтому требуется массив City объектов. Точно так же каждый City имеет массив городов, поэтому для него требуется массив Town объектов.

Предполагая, что вы обращаетесь к JSON из API и хотите преобразовать его в объекты, вам необходимо настроить его на Codable, что довольно просто сделать. По соглашению Swift не использует snake_case для имен переменных, вместо этого он использует регистр верблюда, поэтому вы можете использовать перечисление для ключей кодирования или передать опцию в декодере.

struct MyDataModel: Codable, Identifiable {
    let id: Int
    let firstName: String
    let lastName: String
    let cities: [City]

    enum CodingKeys: String, CodingKey {
        case id
        case firstName = "first_name"
        case lastName = "last_name"
        case cities
    }
}

struct City: Codable {
    let name: String
    let towns: [Town]
}

struct Town: Codable {
    let name: String
}

Обновление

Вы можете сделать что-то подобное с этим, где myDataModels - это массив ваших MyDataModel:

var body: some View {
    List {
        ForEach(myDataModels) { model in
            Section(header: Text("\(model.firstName) \(model.lastName)")) {
                ForEach(model.cities, id: \.name) { (city: City) in
                    Section(header: Text(city.name).fontWeight(.bold)) {
                        ForEach(city.towns, id: \.name) { town in
                            Text(town.name)
                        }
                    }
                }
            }
        }
    }
}

, который будет выглядеть так:

image of possible layout

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...