UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SwiftUI + JSON + MVVM

Forums > SwiftUI

This is probably pretty basic, but I am having a hard time grasping the logic when the JSON doesn't start with an array but has a nested array. This works, but I am sure there is a better approach.

########## JSON INFO ##########

{
"coord": {
"lon": -87.65,
"lat": 41.85
},
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02d"
}
],
"base": "stations",

#################### Grabbing Info from MV ####################

So this work and I can get the correct info, but there seems to be a better way.

// MARK: - BODY
    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            VStack {
                Text(passedWeatherDetails.cityName)
                    .font(.largeTitle)
                    .bold()
                    .padding(.bottom, 20)
                ImageView(url: passedWeatherDetails.weatherIcon)

            } // End VStack
        } // End ScrollView
    }

########## ViewModel ##########

class WeatherViewModel: BaseViewModel {
    @Published var weatherInfo: Weather?
    @Published var weatherDetails: WeatherInfo?
    private var jsonService = JSONService()
    private var weatherSkyInfo = ""
    private var weatherDescriptionInfo = ""
    private var weatherIconInfo = ""

    init(weather: Weather? = nil) {
        self.weatherInfo = weather
    }

    func getWeatherDetails(cityName: String) {
        jsonService.getWeather(cityName: cityName.trimmedAndEscaped()) { result in
            switch result {
            case .success(let detail):
                DispatchQueue.main.async {
                    self.weatherInfo = detail
                    self.loadingState = .success
                    self.getWeatherItems(weatherInfo: self.weatherInfo?.weather ?? [])
                }
            case .failure(let error):
                print(error.localizedDescription)
                DispatchQueue.main.async {
                    self.loadingState = .failed
                }
            }
        }
    }

    func getWeatherItems(weatherInfo: [WeatherInfo]) {
        weatherInfo.forEach { (item) in
            print("Sky: \(item.sky)")
            weatherSkyInfo = item.sky
            print("Description: \(item.description)")
            weatherDescriptionInfo = item.description
            print("Icon: \(item.icon)")
            weatherIconInfo = item.icon
        }
    }

    var cityName: String {
        self.weatherInfo?.cityName ?? "Error Occurred"
    }

    var latitude: Double {
        self.weatherInfo?.coordinates.latitude ?? 0.0
    }

    var longitude: Double {
        self.weatherInfo?.coordinates.longitude ?? 0.0
    }

    var weatherSky: String {
        self.weatherSkyInfo
    }

    var weatherDescription: String {
        self.weatherDescriptionInfo
    }

    var weatherIcon: String {
        self.weatherIconInfo
    }

}

########## Model ##########

struct Weather: Codable {
    let coordinates: Coordinates
    let temperature: Temperature
    let weather: [WeatherInfo]
    let sysInfo: SysInfo
    let timeZone: Int
    let cityName: String

    private enum CodingKeys: String, CodingKey {
        case coordinates = "coord"
        case temperature  = "main"
        case weather = "weather"
        case sysInfo = "sys"
        case timeZone = "timezone"
        case cityName = "name"
    }
}

struct Coordinates: Codable {
    let longitude: Double
    let latitude: Double

    private enum CodingKeys: String, CodingKey {
        case longitude = "lon"
        case latitude = "lat"
    }
}

struct Temperature: Codable {
    let currentTemp: Double
    let feelsLike: Double
    let minTemp: Double
    let maxTemp: Double
    let pressure: Int
    let humidity: Int

    private enum CodingKeys: String, CodingKey {
        case currentTemp = "temp"
        case feelsLike = "feels_like"
        case minTemp = "temp_min"
        case maxTemp = "temp_max"
        case pressure = "pressure"
        case humidity = "humidity"
    }
}

struct WeatherInfo: Codable {
    let sky: String
    let description: String
    let icon: String

    private enum CodingKeys: String, CodingKey {
        case sky = "main"
        case description = "description"
        case icon = "icon"
    }
}

struct SysInfo: Codable {
    let countryCode: String
    let sunrise: Int
    let sunset: Int

    private enum CodingKeys: String, CodingKey {
        case countryCode = "country"
        case sunrise = "sunrise"
        case sunset = "sunset"
    }
}

2      

What is the JsonService can u send me the code ?

2      

What is the JsonService can u send me the code ?

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.