如何解决如何为 SwiftUI 新闻应用程序设置模型
我正在尝试构建一个从 newsapi.org API 数据源返回新闻项目列表的基本应用程序。我将 viewmodel 设置为从 API 获取新闻并将数据转换为模型。然后,我将我的模型设置为围绕 api 响应中的特定项目进行构建(请参阅下面 viewmodel 中 API 的 URL)。最后,我设置了我的 ContentView 以在列表中返回新闻项目。该应用程序构建良好,但新闻项(来源名称、文章标题)未填充在屏幕上,并且在控制台中我收到打印的“失败”消息。我的模型设置不正确吗?文章应该是文章的数组(例如[文章])吗?知道如何设置模型(或视图模型)以在屏幕上填充新闻项目吗?感谢您的反馈。
内容视图
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()
}
}
解决方法
总是打印错误,以防您不确定为什么失败:
print("\(error)") // Instead of print("failed")
如果任何值中包含 null,则将其设为可选:
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?
}
更新视图:
struct ContentView: View {
@ObservedObject var viewModel = NewsViewModel()
var body: some View {
NavigationView {
List(viewModel.articles,id: \.source.id) { news in
VStack {
VStack(alignment: .leading) {
Text(news.source.name ?? "")
Text(news.title)
Text(news.description ?? "")
}
}
}
.navigationTitle("Landmarks")
}
}
}
查看模型更新:
@Published var articles = [Article]()
let model = try JSONDecoder().decode(APIResponse.self,from: data)
//update properties on the main thread
DispatchQueue.main.async {
self.articles = model.articles
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。