ios - 从 JSON 数据 SwiftUI 更新列表
问题描述
我很难理解 JSON 数据应该如何在 SwiftUI 的列表中更新。我正在从 NewsAPI.org 获取数据,我的列表和详细视图工作得很好。我试图弄清楚当我的 json 数据更改时如何使列表保持最新,但数据仍然过时。我仍然是 swift 的初学者,所以如果我犯了错误,任何帮助将不胜感激。
已更新尝试使用 combine 与相同的结果,过时的数据
新数据类
class NewsData: ObservableObject {
var objectWillChange = PassthroughSubject<NewsData, Never>()
@Published var articles = [Article]() {
willSet {
objectWillChange.send(self)
}
}
init() {
guard let url = URL(string: "http://newsapi.org/v2/top-headlines?country=us&apiKey=API_KEY") else { return }
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let response = try? JSONDecoder().decode(News.self, from: data) {
DispatchQueue.main.async() {
self.articles = response.articles
}
}
}
}
.resume()
}
/*
init() {
URLSession.shared
.dataTaskPublisher(for: URLRequest(url: URL(string: "http://newsapi.org/v2/top-headlines?country=us&apiKey=API_KEY")!))
.map(\.data)
.decode(type: News.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
print(error.localizedDescription)
}
}, receiveValue: { data in
self.articles = data.articles
})
.store(in: &self.cancellables)
}
*/
/*
init() {
load()
}
func load() {
guard let url = URL(string: "http://newsapi.org/v2/top-headlines?country=us&apiKey=API_KEY") else { return }
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let response = try? JSONDecoder().decode(News.self, from: data) {
DispatchQueue.main.async() {
self.articles = response.articles
}
}
}
}
.resume()
}
*/
}
我的数据老班
struct News : Codable {
var articles : [Article]
}
struct Article : Codable {
let description : String?
let title : String?
let author: String?
let source: Source
let content: String?
let publishedAt: String?
}
struct Source: Codable {
let name: String?
}
class NewsData: ObservableObject {
@Published var news: News = News(articles: [])
init() {
load()
}
func load() {
guard let url = URL(string: "http://newsapi.org/v2/top-headlines?country=us&apiKey=API_KEY_HERE") else { return }
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let response = try? JSONDecoder().decode(News.self, from: data) {
DispatchQueue.main.async() {
self.news = response
}
}
}
}
.resume()
}
}
我的内容视图
func relativeDate(date: String) -> String {
let formatter = RelativeDateTimeFormatter()
let dateFormatter = ISO8601DateFormatter()
return formatter.localizedString(for: dateFormatter.date(from: date) ?? Date(), relativeTo: Date())
}
struct ContentView: View {
@ObservedObject var news: NewsData
var body: some View {
NavigationView {
List(news.news.articles , id: \.title) { article in
VStack (alignment: .leading, spacing: 5){
Text(article.title ?? "")
.fontWeight(.bold)
.font(.subheadline)
.lineLimit(1)
Text(article.description ?? "")
.font(.subheadline)
.foregroundColor(.secondary)
.lineLimit(1)
Text(relativeDate(date: article.publishedAt ?? ""))
.font(.subheadline)
.foregroundColor(.secondary)
}
}
.navigationTitle("News")
}
}
}
解决方案
推荐阅读
- html - 如果第二列溢出第一列的高度,则滚动它
- c# - 使用反射和 Ado.net 将多个对象动态插入数据库
- python - 为什么这个函数在 JAX 和 numpy 中比较慢?
- amazon-web-services - 如何将生命周期规则应用于 Terraform 中的现有 s3 存储桶?
- javascript - 无法在 javascript 中初始化 XSLTProcessor 构造函数
- angular - 跨域请求被阻止:同源策略不允许读取远程资源
- php - 带有发件人更改的 Postfix 邮件重定向
- kotlin - 如何从类引用或泛型类型中获取属性引用?
- react-native - React Native - UseState,数字键盘不起作用
- json - 我是否需要定义完全相同的 JSON 结构才能将其与 json.Unmarshal 一起使用?