I am very new to Swift and having issues on how to deal with the "String" part from [String : Hour] in my file. Could you please help me?
MeteoClassic.swift as follows:
struct MeteoClassic: Codable {
let lat: Int
let data: DataClass
}
enum CodingKeys: String, CodingKey {
case data
}
struct DataClass: Codable {
let week: [String: Week]
let hours: [String: Hour]
}
struct Hour: Codable {
let temp: Int
let rainfall: Double
enum CodingKeys: String, CodingKey {
case temp, rainfall
}
}
struct Week: Codable {
let date: String
let tmin, tmax: Int
let symbol: String
}
MeteoClassicSevice.swift as follows:
class MeteoClassicSevice {
let url = URL(string: "https://api...")!
func getWeather(completion: @escaping (Result<(MeteoClassic), Error>) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
guard error == nil else {
completion(.failure(error!))
return
}
completion(.success(self.getWeatherResponse(fromData: data!)))
}.resume()
}
private func getWeatherResponse(fromData data: Data) -> (MeteoClassic) {
let weatherData = try? JSONDecoder().decode(MeteoClassic.self, from: data)
if weatherData != nil {
print(weatherData!)
return weatherData!
}
return MeteoClassic(lat: 0, data: DataClass(week: ["err" : Week(date: "We",tmin: 99, tmax: 99, symbol: "ERR")], hours: ["err" : Hour(temp: 44, rainfall: 0.9)]) )
}
}
MeteoClassicTimeline.swift as follows:
...
func getTimeline(in context: Context, completion: @escaping (Timeline<MeteoClassicEntry>) -> Void) {
let currentDate = Date()
let refreshDate = Calendar.current.date(byAdding: .minute, value: 15, to: currentDate)!
MeteoClassicSevice().getWeather { (result) in
let weatherInfo: MeteoClassic
if case .success(let fetchedData) = result {
weatherInfo = fetchedData
print(weatherInfo)
} else {
let errWeather = MeteoClassic(lat: 0, data: DataClass(week: ["err" : Week(date: "Nu" ,tmin: 99, tmax: 99, symbol: "ER")], hours: ["err" : Hour(temp: 44, rainfall: 0.9)]) )
weatherInfo = errWeather
}
let entry = MeteoClassicEntry(date: currentDate, weatherInfo: weatherInfo)
let timeline = Timeline(entries: [entry], policy: .after(refreshDate))
completion(timeline)
}
}
and
struct MeteoClassicEntry: TimelineEntry {
public let date: Date
public let weatherInfo: MeteoClassic}
and the data looks like this:
{"meteostation_place":
...,
"data":{
"week":
{
"day0":{"date":"20210101","tmin":-2,"tmax":4,"symbol":"O"},
"day1":{"date":"20210102","tmin":-3,"tmax":2,"symbol":"O"},
...
},
"hours"
:{"2021010114":
{"temp":4,"datumcas":"2021-01-01T14:00:00+01:00","rainfall":0,"rainfall_probability":0,"symbol":"O","wind_dir":"S","wind_speed":1,"pressure":1006.8},
"2021010115":{"temp":2,"datumcas":"2021-01-01T15:00:00+01:00","rainfall":0,"rainfall_probability":0,"symbol":"O","wind_dir":"SV","wind_speed":1,"pressure":1007.1},
"2021010116":{"temp":1,"datumcas":"2021-01-01T16:00:00+01:00","rainfall":0,"rainfall_probability":0,"symbol":"O","wind_dir":"SZ","wind_speed":2,"pressure":1007.7},
"2021010117":{"temp":-0,"datumcas":"2021-01-01T17:00:00+01:00","rainfall":0,"rainfall_probability":0,"symbol":"O","wind_dir":"SZ","wind_speed":1,"pressure":1008.2},
"2021010118":{"temp":-0,"datumcas":"2021-01-01T18:00:00+01:00","rainfall":0,"rainfall_probability":0,"symbol":"P","wind_dir":"SZ","wind_speed":1,"pressure":1008.6},
...
}
I managed to get from week like this:
struct MeteoClassicMediumView: View {
let weather: MeteoClassic
var body: some View {
let meteoToday = weather.data.week["day0", default: Week(date: "05",tmin: 88, tmax: 99, symbol: "CC")]
...
Text("(meteoToday.tmin)|(meteoToday.tmax)" as String).font(.system(size: 13)).padding(.top, 2)
I found this way how to show the "tmin" and "tmax" in Week.
But I do not know how would I write to show for "day0", "day1"...
let myString = weather.data.week."day0" ...?