11.1 C
London
Saturday, February 10, 2024

ios – SwiftUI not updating UI after fetching knowledge routinely from OpenWeather API


I am going through a problem in my SwiftUI venture the place the UI isn’t updating routinely after fetching knowledge. I’ve a WeatherViewModel fetching climate knowledge for a number of areas, and the UI does not replicate the modifications till I manually set off an replace by urgent a button. I’ve tried utilizing @Revealed properties and ObservableObject, however the issue persists.

I tried to make use of @Revealed properties and ObservableObject in my code.Regardless of these efforts, the UI nonetheless does not replace routinely.

the climate knowledge mannequin:

import Basis

import Basis


// MARK: - Welcome
struct WeatherDataModel: Codable {
    let coord: Coord
    let climate: [Weather]
    let base: String
    let foremost: Primary
    let visibility: Int
    let wind: Wind
    let clouds: Clouds
    let dt: Int
    let sys: Sys
    let timezone, id: Int
    let title: String
    let cod: Int
}

// MARK: - Clouds
struct Clouds: Codable {
    let all: Int
}

// MARK: - Coord
struct Coord: Codable {
    let lon, lat: Double
}

// MARK: - Primary
struct Primary: Codable {
    let temp, feelsLike, tempMin, tempMax: Double
    let strain, humidity: Int

    enum CodingKeys: String, CodingKey {
        case temp
        case feelsLike = "feels_like"
        case tempMin = "temp_min"
        case tempMax = "temp_max"
        case strain, humidity
    }
}

// MARK: - Sys
struct Sys: Codable {
    let kind, id: Int
    let nation: String
    let dawn, sundown: Int
}

// MARK: - Climate
struct Climate: Codable {
    let id: Int
    let foremost, description, icon: String
}

// MARK: - Wind
struct Wind: Codable {
    let velocity: Double
    let deg: Int
}

class Location: ObservableObject, Identifiable {
    let id = UUID()
    @Revealed var title: String
    @Revealed  var weatherDataModel: WeatherDataModel?

    init(title: String) {
           self.title = title
       }

}

class WeatherViewModel: ObservableObject {
    @Revealed var areas: [Location] = []

    func fetchWeather(for location: Location) {
        // Implement API request to OpenWeatherMap utilizing URLSession
        // You may want to interchange "YOUR_API_KEY" along with your precise OpenWeatherMap API key
        let apiKey = "8281a792c5f995747b19a57c8e52ea8d"
        let urlString = "https://api.openweathermap.org/knowledge/2.5/climate?q=(location.title)&appid=(apiKey)"
//        let urlString = "https://api.openweathermap.org/knowledge/2.5/climate?q=mexico&appid=(apiKey)"

        guard let url = URL(string: urlString) else { return }

        URLSession.shared.dataTask(with: url) { knowledge, _, error in
            guard let knowledge = knowledge, error == nil else {

                return }

            do {
                let decodedData = attempt JSONDecoder().decode(WeatherDataModel.self, from: knowledge)
                DispatchQueue.foremost.async {
                    location.weatherDataModel = decodedData
                    print("Climate knowledge fetched efficiently: (decodedData)")
                }
            } catch {
                print("Error decoding climate knowledge: (error)")
            }
        }.resume()
    }
  





}









Additionally for some unusual purpose the view does replace routinely with the .onAppear however then after I click on the button which clearly has no code in it then the view updates and the info from the API is displayed.

the view receiving the info:

//
//  TestView.swift
//  Amun
//
//  Created by Richard Nkanga on 09/02/2024.
//

import SwiftUI

struct HomeView: View {
    @StateObject personal var viewModel = WeatherViewModel()
    @State var names = ["UNITED STATES", "Montreal", "Nigeria", "poland", "London"]
    @State personal var newLocation = "Canada"
    @State personal var isEditing = false

    var physique: some View {
        NavigationStack {
            ZStack {
                Coloration(.background)
                    .ignoresSafeArea(.all)
                    .onAppear {
                    }

                VStack {
                    Checklist(viewModel.areas, id: .id) { locs in

                        HStack {
                            Textual content(locs.title)
                            Textual content("(Double(locs.weatherDataModel?.foremost.temp ?? 0))")

                            Spacer()

                            if let weatherData = locs.weatherDataModel {
                                Textual content("Temp: (Int(weatherData.foremost.temp))°C")
                                Textual content("Temp: (weatherData.title)")
                            } else {
                                Textual content("Loading...")
                            }
                        }
                    }
            
                    .onAppear {
                        for title in names {
                            let location = Location(title: title)
                            viewModel.areas.append(location)
                            viewModel.fetchWeather(for: location)
                        }
                    }

                    Button(motion: {
                        isEditing.toggle()



                    }, label: {
                        Textual content(isEditing ? "Carried out" : "Edit")
                            .foregroundColor(Coloration.purple)

                    })
                }
            }
            .background(Coloration.purple)
            .navigationTitle("Climate")
        }
    }
}

#Preview {
    HomeView()
}

The ui by no means updates and simply retains displaying loading…

Latest news
Related news

LEAVE A REPLY

Please enter your comment!
Please enter your name here