【发布时间】:2021-09-11 09:23:51
【问题描述】:
我正在尝试构建一个从 newsapi.org API 数据源返回新闻项目列表的基本应用程序。我将 viewModel 设置为从 API 获取新闻并将数据转换为模型。然后,我将我的模型设置为围绕 api 响应中的特定项目构建(请参阅下面 viewModel 中的 API URL)。最后,我设置我的 ContentView 以返回列表中的新闻项目。该应用程序构建良好,但新闻项目(来源名称,文章标题)没有填充在屏幕上,并且在控制台中我收到打印的“失败”消息。我的模型设置不正确吗? Article 是否应该是 Article 数组(例如 [Article])?知道如何设置模型(或 viewModel)以在屏幕上填充新闻项目吗?感谢您的反馈。
内容视图
import SwiftUI
struct ContentView: View {
@ObservedObject var viewModel = NewsViewModel()
var body: some View {
NavigationView {
VStack {
List(viewModel.articles, id: \.articles.source.id) { news in
VStack(alignment: .leading) {
Text(news.articles.source.name)
Text(news.articles.title)
Text(news.articles.description)
}
}
}
.navigationTitle("News List")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
型号
import Foundation
struct APIResponse: Codable {
let articles: Article
}
struct Article: Codable {
let source: Source
let title: String
let description: String
}
struct Source: Codable, Identifiable {
let id: String
let name: String
}
视图模型
import Foundation
class NewsViewModel: ObservableObject {
@Published var articles = [APIResponse]()
init() {
fetchNews()
}
func fetchNews() {
guard let url = URL(string: "https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=4b6cfa9b54c74b4db7d7d8a2120718d3") else {
return
}
let task = URLSession.shared.dataTask(with: url) { data, _, error in
guard let data = data, error == nil else {
return
}
do {
let model = try JSONDecoder().decode([APIResponse].self, from: data)
//update properties on the main thread
DispatchQueue.main.async {
self.articles = model
}
}
catch {
print("failed")
}
}
task.resume()
}
}
【问题讨论】:
-
从
dataTask读取响应和错误。 -
@ElTomato 啊...我该怎么做?
-
把
print("failed")改成print(error),你会发现错误,Expected to decode Array<Any> but found a dictionary instead.,这意味着你设置了解码结构错误(即[APIResponse].self)。参考原始 JSON 文件并将articles包装到适合的新结构中。
标签: arrays swift api swiftui swiftui-list