我有json数据,我可以解析导航和名称的第一部分,但是我需要将数组子元素解析为表视图。
{
"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
}
有人有什么想法吗?
我已经有了这些结构,因此当我在其中添加断点时可以看到孩子的名字,但是我不知道如何访问它们并将它们添加到第二部分。下面是我设置的表格视图< / p>
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!
}
}
答案 0 :(得分:0)
I'm not sure how to approach your question since you gave not enough background and information, so I'm going to assume certain things and give you an answer. Let's start!
Looks like the children node is a Nav
array so I created the following structs:
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
}
Inside Menu
I created a getMenu
method. If no parameter is supplied it returns the top level menu else it tries to find a Nav
whose name
property equals the parameter sent.
To decode your json use the following method that receives a JSON string and returns a 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()
}
}
Thats all to decode your JSON to a Menu
struct, now let's deal with the UI stuff. In your viewDidload
or any other entry point in your ViewController
you need to transform your JSON to a Menu
struct. Define a variable for the Menu
and a optional String
variable that has the current menu's name.
var menu: Menu!
var currentMenuOption: String? = nil
Then initialize your navigationMenu with your JSON string:
let navigationMenu = decodeJson(jsonString)
After all of this your extension should look like this:
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!
}
If the user selects a row you must set currentMenuOption
with the row text and reload the table.
This implementation is trying to avoid changing your code as little as possible. Hopes this works for you, or at least give you an idea how to solve it :)