這個問題在這里已經有了答案: 在 SwiftUI 中加載異步請求時顯示活動指示器 2 個答案 20 小時前關閉。
我正在嘗試使用 SwiftUI 構建應用程式,并且我創建了一個負責執行 API 請求并將回應解碼為weatherResponse物件的類,并@Published在此類中注釋了該物件。
在我看來,我已經使用@StateObject注釋實體化了這個類。根據這篇文章,這應該是weatherResponse在我的視圖中觀察物件的正確方法,以便它自動更新。
但是,當我的視圖加載時, 的實體WeatherNetworking甚至還沒有被初始化,因此對該類中發布的物件的第一次參考會導致 nil 值訪問。
struct MainWeatherView: View {
@StateObject var weatherNetworking = WeatherNetworking()
var body: some View {
VStack {
Image(systemName: weatherNetworking.getConditionName(weatherID: (weatherNetworking.weatherResponse!.current.weather[0].id))) // weatherResponse is nil
.resizable()
.aspectRatio( contentMode: .fit)
.scaleEffect(0.75)
.padding()
HStack {
VStack{
Text("Temperature")
.fontWeight(.bold)
.font(.system(size: 24))
Text("Humidity")
.fontWeight(.bold)
.font(.system(size: 24))
...
}
VStack {
Text("\(weatherNetworking.weatherResponse!.current.temp, specifier: "%.2f") °F")
.fontWeight(.bold)
.font(.system(size: 24))
Text("\(weatherNetworking.weatherResponse!.current.humidity, specifier: "%.0f") %")
.fontWeight(.bold)
.font(.system(size: 24))
...
}
}
}
.onAppear {
self.weatherNetworking.getMainWeather()
}
}
}
class WeatherNetworking: ObservableObject {
@StateObject var locationManager = LocationManager()
@Published var weatherResponse: WeatherResponse?
func getMainWeather() {
print("Location:", locationManager.lastLocation?.coordinate.latitude, locationManager.lastLocation?.coordinate.longitude)
if let loc = URL(string: "https://api.openweathermap.org/data/2.5/onecall?appid=redacted&exclude=minutely&units=imperial&lat=\(locationManager.lastLocation?.coordinate.latitude ?? 0)&lon=\(locationManager.lastLocation?.coordinate.longitude ?? 0)") {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: loc) { data, response, error in
if error == nil {
let decoder = JSONDecoder()
if let safeData = data {
do {
let results = try decoder.decode(WeatherResponse.self, from: safeData)
DispatchQueue.main.async {
self.weatherResponse = results
}
print("weatherResponse was succesfully updated")
} catch {
print(error)
}
}
} else {
print(error!)
}
}
task.resume()
}
}
}
執行中沒有任何列印陳述句getMainWeather()使我相信視圖正在嘗試在呼叫函式之前分配值。如何在我的視圖中延遲這些值的分配,直到onAppear()方法完成之后?值得注意的是,正如MainWeatherView依賴于實體化和異步呼叫一樣WeatherNetworking,也WeatherNetworking依賴于LocationManager.
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
@Published var locationStatus: CLAuthorizationStatus?
@Published var lastLocation: CLLocation?
...
}
uj5u.com熱心網友回復:
使依賴視圖有條件,例如
VStack {
if let response = weatherNetworking.weatherResponse {
Image(systemName: weatherNetworking.getConditionName(weatherID: (response.current.weather[0].id))) // weatherResponse is nil
.resizable()
.aspectRatio( contentMode: .fit)
.scaleEffect(0.75)
.padding()
}
// .. other code
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/489758.html
