使用 JSON 解码器解压嵌套的 JSON 值
Use JSONDecoder to unpack nested JSON values
如何从此 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
}
}
和第二关的模式完全一样。您必须为任何字典创建一个单独的 struct / class 。结构的名称是任意的。父结构中的 属性 / class 必须匹配字典键(在本例中为 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 其中 returns 始终是一个有效的单元格:
let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath) as! UserEventsTableViewCell
如何从此 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
}
}
和第二关的模式完全一样。您必须为任何字典创建一个单独的 struct / class 。结构的名称是任意的。父结构中的 属性 / class 必须匹配字典键(在本例中为 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 其中 returns 始终是一个有效的单元格:
let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath) as! UserEventsTableViewCell