我正在做一个小项目,以练习使用结构在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)
已经做到了。
答案 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.headlines
,self.abstracts
,self.urls
和self.images
。但是您的表视图对此一无所知。它完全取决于另一个数组storyData
。如果您明白我的意思,则需要将这两个数据模型放在一起。下载数据,将其重新映射到storyData
,然后将表视图告知reloadData
。