使用 Codable 解析多级 JSON
Parsing multi-level JSON with Codable
我正在尝试将以下 JSON 解析为 tableView
:https://www.pathofexile.com/api/trade/data/items
我成功解析了第一个数组,但是我无法解析键 "entries"...
这是我的代码,具有我定义的数据结构:
import UIKit
struct ItemCategories: Codable {
var result: [ItemCategory]
}
struct ItemCategory: Codable {
var label: String
var entries: [Item]
}
struct Item: Codable {
// empty struct
}
class ViewController: UITableViewController {
let urlString = "https://www.pathofexile.com/api/trade/data/items"
var categories = [ItemCategory]()
override func viewDidLoad() {
super.viewDidLoad()
title = "Path of Data"
navigationController?.navigationBar.prefersLargeTitles = true
parse()
}
func parse() {
guard let url = URL(string: urlString) else { return }
guard let data = try? Data(contentsOf: url) else { return }
let decoder = JSONDecoder()
guard let jsonItemCategories = try? decoder.decode(ItemCategories.self, from: data) else { return }
categories = jsonItemCategories.result
tableView.reloadData()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
var categoryName = categories[indexPath.row].label
if categoryName == "" { categoryName = "Unknown" }
cell.textLabel?.text = categoryName
cell.textLabel?.textColor = .systemOrange
let numberOfItemsInCategory = String(categories[indexPath.row].entries.count)
cell.detailTextLabel?.text = numberOfItemsInCategory + " items"
return cell
}
}
struct Item是空的,因为当我尝试添加对应于JSON中的键的变量时,整个解析失败(tableView什么都不显示)。
当struct Item为空时,解析成功,tableView可以显示不同的分类。由于
,它甚至显示每个 "entries" 的项目数
let numberOfItemsInCategory = String(categories[indexPath.row].entries.count)
cell.detailTextLabel?.text = numberOfItemsInCategory + " items"
有人可以解释为什么吗?理想情况下,我想在点击行时显示 "entries" 的内容,但我暂时不知道该怎么做。
谢谢你的帮助:)
screenshot
@Laurent Delorme 你的结构 Item
应该像下面这样,试试这个,
struct Item: Codable {
let name: String?
let type: String?
let text: String?
let flags: FlagsRepresentation?
enum CodingKeys: String, CodingKey {
case name
case type
case text
case flags
}
}
struct FlagsRepresentation: Codable {
let unique: Bool?
enum CodingKeys: String, CodingKey {
case unique
}
}
我正在尝试将以下 JSON 解析为 tableView
:https://www.pathofexile.com/api/trade/data/items
我成功解析了第一个数组,但是我无法解析键 "entries"...
这是我的代码,具有我定义的数据结构:
import UIKit
struct ItemCategories: Codable {
var result: [ItemCategory]
}
struct ItemCategory: Codable {
var label: String
var entries: [Item]
}
struct Item: Codable {
// empty struct
}
class ViewController: UITableViewController {
let urlString = "https://www.pathofexile.com/api/trade/data/items"
var categories = [ItemCategory]()
override func viewDidLoad() {
super.viewDidLoad()
title = "Path of Data"
navigationController?.navigationBar.prefersLargeTitles = true
parse()
}
func parse() {
guard let url = URL(string: urlString) else { return }
guard let data = try? Data(contentsOf: url) else { return }
let decoder = JSONDecoder()
guard let jsonItemCategories = try? decoder.decode(ItemCategories.self, from: data) else { return }
categories = jsonItemCategories.result
tableView.reloadData()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
var categoryName = categories[indexPath.row].label
if categoryName == "" { categoryName = "Unknown" }
cell.textLabel?.text = categoryName
cell.textLabel?.textColor = .systemOrange
let numberOfItemsInCategory = String(categories[indexPath.row].entries.count)
cell.detailTextLabel?.text = numberOfItemsInCategory + " items"
return cell
}
}
struct Item是空的,因为当我尝试添加对应于JSON中的键的变量时,整个解析失败(tableView什么都不显示)。
当struct Item为空时,解析成功,tableView可以显示不同的分类。由于
,它甚至显示每个 "entries" 的项目数let numberOfItemsInCategory = String(categories[indexPath.row].entries.count)
cell.detailTextLabel?.text = numberOfItemsInCategory + " items"
有人可以解释为什么吗?理想情况下,我想在点击行时显示 "entries" 的内容,但我暂时不知道该怎么做。
谢谢你的帮助:)
screenshot
@Laurent Delorme 你的结构 Item
应该像下面这样,试试这个,
struct Item: Codable {
let name: String?
let type: String?
let text: String?
let flags: FlagsRepresentation?
enum CodingKeys: String, CodingKey {
case name
case type
case text
case flags
}
}
struct FlagsRepresentation: Codable {
let unique: Bool?
enum CodingKeys: String, CodingKey {
case unique
}
}