从结构而不是数组填充tableview

时间:2018-10-21 21:16:19

标签: ios json swift struct

我正在做一个小项目,以练习使用结构在Swift 4中序列化JSON ...它从《纽约时报》 API中获取最新消息并将其放入表格视图中。目前,我正在从JSON获取所需的数据,并用所需的内容(标题,摘要等)填充一些数组。

有人建议我跳过这一步,而直接从结构中填充表视图。

struct TopStoriesResponse: Decodable {
    let status: String
    let results: [Story]
}

struct Story: Decodable {
    let title: String
    let abstract: String
    let url: String
    let multimedia: [Multimedia]

    private enum CodingKeys: String, CodingKey {
        case title
        case abstract
        case url
        case multimedia
    }

    init(from decoder:Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        title = try container.decode(String.self, forKey: .title)
        abstract = try container.decode(String.self, forKey: .abstract)
        url = try container.decode(String.self, forKey: .url)
        multimedia = (try? container.decode([Multimedia].self, forKey: .multimedia)) ?? []
    }

}

struct Multimedia: Decodable {
    let url: String
    let type: String
}

var storyData = [Story]()

在我的cellForRowAt方法中:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "storyCell", for: indexPath) as! StoryTableViewCell

    let stories = storyData[indexPath.row]

    print("Titles: \(stories.title)")

    cell.headlineLabel.text = stories.title
    cell.abstractLabel.text = stories.abstract

    return cell
}

当我运行该应用程序时,表视图为空,并且我的打印语句确认stories.title为空(所有出现在我使用数组之前的内容)。

如果适用于此函数,则该函数将捕获数据,如果可以使用结构代替,我将废弃将数据传递给数组的所有代码:

func getJSON(completionHandler: @escaping (Bool) -> ()) {
    let jsonUrlString = "https://api.nytimes.com/svc/topstories/v1/business.json?api-key=f4bf2ee721031a344b84b0449cfdb589:1:73741808"
    guard let url = URL(string: jsonUrlString) else {return}

    URLSession.shared.dataTask(with: url) { (data, response, err) in
        guard let data = data, err == nil else {
            print(err!)
            return
        }

        do {
            let response = try
                JSONDecoder().decode(TopStoriesResponse.self, from: data)

            // Pass results into arrays (title, abstract, url, image)
            for result in response.results {
                let headlines = result.title
                let abstracts = result.abstract
                let url = result.url

                self.headlines.append(headlines)
                self.abstracts.append(abstracts)
                self.urls.append(url)

                for imageResults in result.multimedia {
                    let images = imageResults.url
                    self.images.append(images)
                }
            }

            completionHandler(true)

        } catch let jsonErr {
            print("Error serializing JSON", jsonErr)
        }
    }.resume()
}

我是否需要像处理数组那样将数据传递回结构中?我觉得let response = try JSONDecoder().decode(TopStoriesResponse.self, from: data)已经做到了。

2 个答案:

答案 0 :(得分:1)

您需要

let response = try  JSONDecoder().decode(TopStoriesResponse.self, from: data)
self.storyData = response.results
DispatchQueue.main.async {
  self.tableView.reloadData()
}

其他数组内容在这里无关紧要,因为您不将它们用作表的数据源

答案 1 :(得分:1)

您的数据模型似乎不匹配。一方面,您的JSON数据被放入四个数组中:self.headlinesself.abstractsself.urlsself.images。但是您的表视图对此一无所知。它完全取决于另一个数组storyData。如果您明白我的意思,则需要将这两个数据模型放在一起。下载数据,将其重新映射到storyData,然后将表视图告知reloadData