Заполнение данных JSON в табличном представлении Swift 4 - PullRequest
1 голос
/ 02 мая 2019

У меня есть данные json, и я могу проанализировать первую часть, которая называется nav и name, однако мне нужно проанализировать дочерние элементы массива в табличном представлении.

{
"nav": [
    {
        "name": "Home",
        "navigationName": "Home",
        "icon": null,
        "navigation": {
            "URI": null,
            "type": "CUSTOM",
            "target": "home",
            "depth": null,
            "data": null,
            "filters": {},
            "urlStructure": {
                "title": null,
                "isFeatured": false,
                "isCampaign": false
            }
        },
        "styles": []
    },
    {
        "name": "New In",
        "navigationName": "New In",
        "icon": null,
        "navigation": {
            "URI": null,
            "type": "NO_LINK",
            "target": "",
            "depth": null,
            "data": null,
            "filters": {},
            "urlStructure": {
                "title": null,
                "isFeatured": false,
                "isCampaign": false
            }
        },
        "styles": [
            "linkNewin"
        ],
        "children": [
            {
                "name": "New In Mens",
                "navigationName": "New In Mens",
                "icon": null,
                "navigation": {
                    "URI": "/men?facet:new=latest&sort=latest",
                    "type": "CATEGORY",
                    "target": "men",
                    "depth": null,
                    "data": null,
                    "filters": {
                        "facet:new": "latest",
                        "sort": "latest"
                    },
                    "urlStructure": {
                        "title": null,
                        "isFeatured": false,
                        "isCampaign": false
                    }
                },
                "styles": [
                    "linkNewin"
                ]
            },

Это данные json.Я проанализировал и заполнил первое имя в массиве nav, но не могу сделать это для массива Children.Я уже создал эту модель данных:

    struct Menu: Codable {
    var nav: [Menus]

}

struct Menus: Codable {
    var name: String
    var children: [Child]?


}

struct Child: Codable {
    var name: String
}

У кого-нибудь есть идеи?

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

extension MenuViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 32
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: "cell")

        if cell == nil {
            cell = UITableViewCell.init(style: .value1, reuseIdentifier: "cell")
        }
        let navItem = self.menu?.nav[indexPath.row]
//        cell?.det?.text = self.menu?.nav[indexPath.row].children?[indexPath.row].name


        return cell!
    }


}

1 Ответ

0 голосов
/ 19 мая 2019

Я не уверен, как подойти к вашему вопросу, так как вы дали недостаточно информации и информации, поэтому я собираюсь принять некоторые вещи и дать вам ответ.Давайте начнем!

Похоже, что дочерний узел - это массив Nav, поэтому я создал следующие структуры:

struct Menu: Codable {
    let nav: [Nav]

    func getMenu(_ parent: String? = nil) -> [Nav] {
        if parent == nil {
            return nav
        } else {
            let option =
                nav.compactMap { $0 }
                   .first { $0.name == parent }
            if let children = option?.children {
                return children
            } else {
                return []
            }
        }
    }
}

struct Nav: Codable {
    let name, navigationName: String
    let icon: String?
    let navigation: Navigation
    let styles: [String]
    let children: [Nav]?
}

struct Navigation: Codable {
    let URI: String?
    let type: String
    let target: String
    let depth: Int?
    let data: String?
    let filter: [String:String]?
    let urlStructure: UrlStructure
}

struct UrlStructure: Codable {
    let title: String?
    let isFeatured: Bool
    let isCampaign: Bool
}

Внутри Menu Я создал метод getMenu.Если параметр не указан, он возвращает меню верхнего уровня, в противном случае он пытается найти Nav, свойство name которого равно отправленному параметру.Чтобы декодировать ваш json, используйте следующий метод, который получает строку JSON и возвращает Menu:

func decodeJson(_ jsonString: String) -> Menu {
    let decoder = JSONDecoder()
    // Try to get JSON from String to Data
    guard let jsonData = jsonString.data(using: .utf8) else { return Menu() }
    do {
        return try decoder.decode(Menu.self, from: jsonData)
    } catch { // Decode, if bad JSON return empty Menu
        return Menu()
    }
}

Все это для декодирования вашего JSON в структуру Menu, теперь давайте разберемся с пользовательским интерфейсом.В вашей viewDidload или любой другой точке входа в ViewController вам необходимо преобразовать JSON в Menu структуру.Определите переменную для Menu и необязательную переменную String, которая имеет имя текущего меню.

var menu: Menu!
var currentMenuOption: String? = nil

Затем инициализируйте ваше навигационное меню строкой JSON:

let navigationMenu = decodeJson(jsonString)

Послевсе это ваше расширение должно выглядеть так:

extension MenuViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return navigationMenu.getMenu(currentMenuOption).count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: "cell")

        if cell == nil {
            cell = UITableViewCell.init(style: .value1, reuseIdentifier: "cell")
        }
        let navItem = self.menu.getMenu(currentMenuOption)[indexPath.row]
            cell?.det?.text = navItem.name
        return cell!
    }

Если пользователь выбирает строку, вы должны установить currentMenuOption с текстом строки и перезагрузить таблицу.Эта реализация пытается избежать изменения вашего кода как можно меньше.Надеюсь, что это работает для вас, или, по крайней мере, дать вам представление о том, как ее решить:)

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