使用 JSONDecoder 解包嵌套的 JSON 值
Posted
技术标签:
【中文标题】使用 JSONDecoder 解包嵌套的 JSON 值【英文标题】:Use JSONDecoder to unpack nested JSON values 【发布时间】:2017-12-28 20:44:39 【问题描述】:如何从该 JSON 数据中获取三级值?
"data": [
"id": "1669690663119337",
"name": "Event1",
"attending_count": 17,
"cover":
"offset_x": 0,
"offset_y": 50,
"source": "https://imageurl",
"id": "1769679396399074"
,
"id": "130418660933615",
"name": "Event2",
"attending_count": 923,
"cover":
"offset_x": 0,
"offset_y": 50,
"source": "https://imageurl",
"id": "10156609677937586"
,
"id": "1883372648594017",
"name": "Event3",
"attending_count": 1695,
"cover":
"offset_x": 0,
"offset_y": 50,
"source": "imageurl",
"id": "10156575272607586"
对于二级值(id、name、attending_count),我使用这些代码行:
struct JsonFromWeb: Codable
let data: [Course]
struct Course: Codable
let id: String?
let name: String?
let attending_count: Int?
class JsonViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
@IBOutlet var eventTable: UITableView!
var event = [Course]()
override func viewDidLoad()
super.viewDidLoad()
let jsonUrlString = "https://www.jsonurl.url/"
guard let url = URL(string: jsonUrlString) else return
print(jsonUrlString)
URLSession.shared.dataTask(with: url) (data, response, err) in
guard let data = data else return
do
let courses = try JSONDecoder().decode(JsonFromWeb.self, from: data)
self.event = courses.data
DispatchQueue.main.async
self.eventTable.reloadData()
catch let jsonErr
print("Error jsonErr", jsonErr)
.resume()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return event.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
guard let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell") as? UserEventsTableViewCell else return UITableViewCell()
cell.nameLabel.text = event[indexPath.row].name
return cell
【问题讨论】:
【参考方案1】:这与第二级的模式完全相同。您必须为任何字典创建一个单独的结构/类。结构的名称是任意的。父结构/类中的属性必须匹配字典键(本例中为cover
)
struct JsonFromWeb: Codable
let data: [Course]
struct Course: Codable
private enum CodingKeys : String, CodingKey
case attendingCount = "attending_count"
case id, name, cover
let id: String
let name: String
let attendingCount: Int
let cover: Cover
struct Cover : Codable
private enum CodingKeys : String, CodingKey
case offsetX = "offset_x"
case offsetY = "offset_y"
case source, id
let offsetX: Int
let offsetY: Int
let source: String
let id: String
注意:
从不使用这种语法
guard let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell") as? UserEventsTableViewCell else
return UITableViewCell()
这是推荐强制展开以发现设计错误的少数情况之一。如果一切都正确连接,则代码不得崩溃。并使用始终返回有效单元格的dequeue
API:
let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath) as! UserEventsTableViewCell
【讨论】:
首先,非常感谢您这么快回答。但是你能帮我把这个“源”变量添加到表中吗,就像我添加了“名称”变量一样?这将使我的一天:) 使用这个:让课程=尝试 JSONDecoder().decode(JsonFromWeb.self, from: data) self.event = courses.data 有什么问题?您的代码应该可以工作。如果没有显示数据,则错误与自定义表格视图单元格有关 当我用您的代码替换我的部分代码时,会出现错误:(_BD6BE31D58877246570CAEB111C1E2ED 中的 CodingKeys).data,Foundation.(_12768CA107A31EF2DCE034FD75B541C9 中的_JSONKey)(stringValue:“索引 17”,intValue:可选( 17))], debugDescription: "No value associated with key cover (\"cover\").", underlyingError: nil)) 而且我不应该将它与变量一起使用? : cell.nameLabel.text = event[indexPath.row].name 如果cover
可以是nil
而不是使cover
可选:let cover: Cover?
是的,现在可以了。再次感谢您,您对我帮助很大! :)以上是关于使用 JSONDecoder 解包嵌套的 JSON 值的主要内容,如果未能解决你的问题,请参考以下文章
如何在 swift 4 中使用 JSONDecoder 从嵌套 JSON 中获取数据?