在我说其他之前,我实际上是Swift和SwiftUI的初学者,但我总是试图完成不符合我知识水平的事情。我有一个想法,把巴士信息带到现场活动中。我设法找到了一个本地交通的API,并创建了一个SwiftUI列表视图,用于显示特定公交车站的下一辆公交车。
YouTube上有一个教程,展示了如何获取数据(https://www.youtube.com/watch?v=CimY_Sr3gWw&t=221),他使用了@Published var bus:[BusAPI] = []让视图知道当API数据改变时,它必须刷新。
我用这种方式获取API数据。
import Foundation
import SwiftUI
struct BusAPI: Hashable, Codable {
let route_code: String
let veh_code: String
let btime2: String
}
class ViewModel: ObservableObject {
@Published var bus: [BusAPI] = []
func fetch() {
guard let url = URL(string: "http://telematics.oasa.gr/api/?act=getStopArrivals&p1=060475") else {
return
}
let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
guard let data = data, error == nil else {
return
}
//Convert to JSON
do {
let bus = try JSONDecoder().decode([BusAPI].self, from: data)
DispatchQueue.main.async {
self?.bus = bus
}
}
catch {
print(error)
}
}
task.resume()
}
}
视图如下所示:
//
// ContentView.swift
// BusDemoAPI
//
import SwiftUI
struct ContentView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
NavigationView {
List {
ForEach(viewModel.bus, id: \.self) { bus in
HStack {
Text("N. Ελβετία - Άνω Πατήσια")
Spacer()
Text("\(bus.btime2)'")
}.padding(3)
}
}.navigationTitle("Στάση ΟΠΑ")
.onAppear {
viewModel.fetch()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我的实际问题是,为什么当数据更改时视图不刷新?它总是停留在第一次获取数据的时间。
我试图在谷歌上找到一个解决方案,但没有任何实际帮助。
2条答案
按热度按时间jslywgbw1#
在您的代码中,您正确地使用了@Published来指示总线数组是一个可观察属性。每当数据发生更改时,这将触发视图的刷新。但是,代码中可能存在一个小错误,导致视图无法刷新。
这个问题似乎与以下事实有关:在fetch()方法中有两个同名的变量(bus)。一个是视图模型中的BusAPI对象数组,另一个是do-catch块中的本地常量,在这里解码JSON响应。
要解决此问题,可以为do-catch块内的局部常量指定不同的名称。下面是修改后的fetch()方法:
通过为局部常量提供不同的名称(在本例中为decodedBus),可以避免隐藏视图模型的总线属性,从而允许将获取的数据正确分配给observable属性。每当获取新数据时,这应该会按预期触发视图刷新。
尝试一下这个修改,看看它是否解决了数据更改时视图不刷新的问题。
htzpubme2#
你的问题
My actual question is why doesnt the view refreshes when the data changes?
的答案是,当服务器上的数据更新时,你的代码不会自动更新。当您决定这样做时,您需要自己获取new
数据。一个简单的方法是在
List
中添加一个.refreshable
修饰符,这样当用户执行拉刷新手势(快速向下滑动列表)时,列表内容会被重新获取,从而更新为最新的巴士信息。注意,您使用的是不安全的
http
连接,Apple要求使用https
。