SwiftUI - update view on weather condition change

80 Views Asked by At

Very new to coding and to Swift (please, don't hate me). Working on a simple weather app based on WeatherKit. I need to update the content of a View in real-time, when the weather condition changes.

This is my view:

  import SwiftUI
  import WeatherKit


struct ContentView: View {

@ObservedObject var weatherKitManager = WeatherKitManager()
@State var showView = false

var body: some View {
    
    NavigationStack {
        switch weatherKitManager.state {
        case .idle: EmptyView()
        case .loading: ProgressView()
        case .success(let weather):

        ......
        ......
        ......

        ZStack {
                  HStack (spacing: 8) {
                     Text(weather.currentWeather.temperature.formatted())
                     Text("\(weatherKitManager.condition.emoji)")
                     .font(.system(size: 22))
                     .zIndex(10)
                     .padding(5)
                     .overlay(
                        Rectangle()
                        .fill(.white)
                        .cornerRadius(20)
                        .opacity(0.3)
                        .zIndex(-8)
                     )
        }

        ......
        ......
        ......

        case .failure(let error):
            Text(error.localizedDescription)
                .font(.largeTitle)
        }
      }
    .task {
        await weatherKitManager.getWeather()
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .ignoresSafeArea()
   }
   }

   struct ContentView_Previews: PreviewProvider {
      static var previews: some View {
         ForEach(ColorScheme.allCases, id: \.self, content: 
         ContentView().preferredColorScheme)
      }
   }

and this is my WeatherKitManager:

import Foundation
import WeatherKit
import SwiftUI
import CoreLocation

        ......
        ......
        ......

@MainActor class WeatherKitManager: ObservableObject {

@Published var weather: Weather?
@Published var state: LoadingState = .idle
@Published var condition: WeatherCondition = .clear

enum LoadingState {
    case idle, loading, success(Weather), failure(Error)
}

func getWeather() async {
        state = .loading
        do {
            let weather = try await WeatherService.shared.weather(for: 
            .init(latitude: 42.34779, longitude: 13.39943)) 
            state = .success(weather)
            condition = weather.currentWeather.condition
        } catch {
            state = .failure(error)
        }
 }

I'd like to understand how to make a change in real-time or based on a Timer. Thank you.

0

There are 0 best solutions below