ios - Swift 4 - 将类结构的 JSON 响应嵌套到 TableViewCell 中
问题描述
我有以下结构来帮助从 JSON Web api 返回数据:
// To parse the JSON, add this file to your project and do:
//
// let story = try? JSONDecoder().decode(Story.self, from: jsonData)
import Foundation
typealias Story = [StoryElement]
struct StoryElement: Codable {
let id: Int
let url: String
let storyPublic, featured: Bool
let added, modified: String
let itemType: ItemType
let collection: JSONNull?
let owner: Owner
let files: Files
let tags: [ItemType]
let elementTexts: [ElementText]
let extendedResources: ExtendedResources
enum CodingKeys: String, CodingKey {
case id, url
case storyPublic = "public"
case featured, added, modified
case itemType = "item_type"
case collection, owner, files, tags
case elementTexts = "element_texts"
case extendedResources = "extended_resources"
}
}
struct ElementText: Codable {
let html: Bool
let text: String
let elementSet: ElementSet
let element: Element
enum CodingKeys: String, CodingKey {
case html, text
case elementSet = "element_set"
case element
}
}
struct Element: Codable {
let id: Int
let url, name: String
let resource: ElementResource
}
enum ElementResource: String, Codable {
case elements = "elements"
}
struct ElementSet: Codable {
let id: Int
let url: URL
let name: Name
let resource: ElementSetResource
}
enum Name: String, Codable {
case dublinCore = "Dublin Core"
case itemTypeMetadata = "Item Type Metadata"
}
enum ElementSetResource: String, Codable {
case elementSets = "element_sets"
}
enum URL: String, Codable {
case httpWWWRalstoncemeteryCOMGreeleyAPIElementSets1 = "http://www.ralstoncemetery.com/greeley/api/element_sets/1"
case httpWWWRalstoncemeteryCOMGreeleyAPIElementSets3 = "http://www.ralstoncemetery.com/greeley/api/element_sets/3"
}
struct ExtendedResources: Codable {
let exhibitPages: Files
let geolocations: Owner
enum CodingKeys: String, CodingKey {
case exhibitPages = "exhibit_pages"
case geolocations
}
}
struct Files: Codable {
let count: Int
let url, resource: String
}
struct Owner: Codable {
let id: Int
let url, resource: String
}
struct ItemType: Codable {
let id: Int
let url, name, resource: String
}
// MARK: Encode/decode helpers
class JSONNull: Codable {
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
您可以在此处查看我正在使用的 JSON 输出以及原始结构:https ://app.quicktype.io?share=oAMNjooSzgpraWpf1KIj (仅供参考)。
数据(我相信)已成功返回并正确解析,唯一的问题归结为我自己不那么熟悉(我正在尝试了解更多信息)。
所以我有一个 TableViewController 并且我有一个单元格,其中包含以下代码:
struct StoryCellViewModel {
let id: Int
let url: String
let storyPublic, featured: Bool
let added, modified: String
}
在 viewDidLoad() 下的实际 TableViewController 中,我有这部分脚本:
print(story)
self.cellViewModels = story.map{
StoryCellViewModel(id: $0.id, url: $0.url, storyPublic: $0.storyPublic, featured: $0.featured, added: $0.added, modified: $0.modified)
}
比这低一点,我有:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "StoryCell", for: indexPath)
let cellViewModel = cellViewModels[indexPath.row]
cell.textLabel?.text = String(cellViewModel.id)
cell.detailTextLabel?.text = cellViewModel.modified
return cell
}
我会让大家知道所有这些工作,id 和修改(都只是用作测试以确保连接和打印正常工作)都很好,但我的问题出现在这里:
如果我们回到结构有这部分:
struct ElementText: Codable {
let html: Bool
let text: String
let elementSet: ElementSet
let element: Element
enum CodingKeys: String, CodingKey {
case html, text
case elementSet = "element_set"
case element
}
}
它指的是示例 JSON 的以下部分:
"element_texts": [
{
"html": false,
"text": "Woehler and Force Farm Equipment Building",
"element_set": {
"id": 1,
"url": "http://www.ralstoncemetery.com/greeley/api/element_sets/1",
"name": "Dublin Core",
"resource": "element_sets"
},
"element": {
"id": 50,
"url": "http://www.ralstoncemetery.com/greeley/api/elements/50",
"name": "Title",
"resource": "elements"
}
},
{
"html": false,
"text": "Woehler and Force Farm Equipment",
"element_set": {
"id": 1,
"url": "http://www.ralstoncemetery.com/greeley/api/element_sets/1",
"name": "Dublin Core",
"resource": "element_sets"
},
"element": {
"id": 39,
"url": "http://www.ralstoncemetery.com/greeley/api/elements/39",
"name": "Creator",
"resource": "elements"
}
},
{
"html": false,
"text": "Street view of the front exterior of Woehler and Force Farm Equipment. Several automobiles are visible through the windows of the store. The alley along the side of the building is also visible. There are several signs along the front of the building reading, 'Farm Equipment,' 'Kaiser Frazer W&F,' and 'Woehler & Force.'; Verso There is a sticker with typed black ink reading, 'Woehler & Force 1316-22 8th Ave. - Greeley, CO 1947. Orig. env. says Liberty Trucker Parts Co./ 690 Lincoln St./F.V. Altwater/POB 1889/Denver, Colo.'",
"element_set": {
"id": 3,
"url": "http://www.ralstoncemetery.com/greeley/api/element_sets/3",
"name": "Item Type Metadata",
"resource": "element_sets"
},
"element": {
"id": 54,
"url": "http://www.ralstoncemetery.com/greeley/api/elements/54",
"name": "Story",
"resource": "elements"
}
}
],
**所以我的问题是:** 我将如何打印出第一个element_texts
(为该text
领域设置“Woehler and Force Farm Equipment Building”的那个)?
如果需要任何进一步的解释,我很乐意输入。或者,如果有人有任何资源用于这种级别的嵌套,我将非常感激。谢谢 -
解决方案
story
是一个数组StoryElement
(为什么不stories
呢?)- 属性的类型
elementTexts
是StoryElement
一个数组ElementText
所以基本上你需要两个循环来迭代story
和elementTexts
for aStory in story {
for elementText in aStory.elementTexts {
print(elementText.text)
}
}
推荐阅读
- node.js - NodeJS:从响应中读取 XLS 文件并转换为 json?
- arm - 如何使用 qemu 在 x86 主机上启动 ARM vm?
- algorithm - 迭代归并排序的运行时间和不变量是多少?
- javascript - 用户接受后,我的 Div 不断弹出
- mysql - SQL 查询:JSON 列差异
- java - 如何启用activemq插件
- python - 带有pygame同步问题的Python游戏
- javascript - 使用 JavaScript 刷新站点时更改 URL 路径
- java - 解析 docx 并忽略图标
- regex - Apache RewriteRule 与新 URL 中的与号