Commit 9254d554 by Dmitriy Stepanets

Data models changes

parent 035622d5
...@@ -11,6 +11,13 @@ import Foundation ...@@ -11,6 +11,13 @@ import Foundation
/// Needed for XMLCoder to decode the array with the right key name /// Needed for XMLCoder to decode the array with the right key name
struct WdtDailySummariesArray: Codable { struct WdtDailySummariesArray: Codable {
private static let dateFormatter:DateFormatter = {
let fmt = DateFormatter()
fmt.timeZone = TimeZone(abbreviation: "PST")
fmt.dateFormat = "MM/dd/YYYY"
return fmt
}()
let items: [WdtDailySummary] let items: [WdtDailySummary]
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
...@@ -18,10 +25,23 @@ struct WdtDailySummariesArray: Codable { ...@@ -18,10 +25,23 @@ struct WdtDailySummariesArray: Codable {
case items = "daily_summary" case items = "daily_summary"
} }
init(from decoder: Decoder) throws {
func validate(dateString:String) -> Bool {
return WdtDailySummariesArray.dateFormatter.date(from: dateString) != nil
}
let container = try decoder.container(keyedBy: CodingKeys.self)
var rawItems = try container.decode([WdtDailySummary].self, forKey: .items)
rawItems = (rawItems.filter{ validate(dateString: $0.dateLocal) })
self.items = rawItems
}
func toAppModel(timeZone: TimeZone, updatedAt: Date) throws -> [DailyWeather] { func toAppModel(timeZone: TimeZone, updatedAt: Date) throws -> [DailyWeather] {
var result = [DailyWeather]() var result = [DailyWeather]()
for item in items { for item in items {
result.append(try item.toAppModel(timeZone: timeZone, updatedAt: updatedAt)) if let appModel = item.toAppModel(timeZone: timeZone, updatedAt: updatedAt) {
result.append(appModel)
}
} }
return result return result
} }
......
...@@ -10,6 +10,13 @@ import Foundation ...@@ -10,6 +10,13 @@ import Foundation
/// Needed for XMLCoder to decode the array with the right key name /// Needed for XMLCoder to decode the array with the right key name
struct WdtHourlySummariesArray: Codable { struct WdtHourlySummariesArray: Codable {
private static let dateFormatter:DateFormatter = {
let fmt = DateFormatter()
fmt.timeZone = TimeZone(abbreviation: "PST")
fmt.dateFormat = "YYYY-MM-dd HH:mm:ss"
return fmt
}()
let items: [WdtHourlySummary] let items: [WdtHourlySummary]
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
...@@ -17,10 +24,27 @@ struct WdtHourlySummariesArray: Codable { ...@@ -17,10 +24,27 @@ struct WdtHourlySummariesArray: Codable {
case items = "hourly_summary" case items = "hourly_summary"
} }
init(from decoder: Decoder) throws {
func validate(dateString:String) -> Bool {
let result = WdtHourlySummariesArray.dateFormatter.date(from: dateString)
if result == nil {
print("[WdtHourly] Could't validate date: \(dateString)")
}
return result != nil
}
let container = try decoder.container(keyedBy: CodingKeys.self)
var rawItems = try container.decode([WdtHourlySummary].self, forKey: .items)
rawItems = (rawItems.filter{ validate(dateString: $0.dateTimeLocal) })
self.items = rawItems
}
func toAppModel(timeZone: TimeZone, updatedAt: Date) throws -> [HourlyWeather] { func toAppModel(timeZone: TimeZone, updatedAt: Date) throws -> [HourlyWeather] {
var result = [HourlyWeather]() var result = [HourlyWeather]()
for item in items { for item in items {
result.append(try item.toAppModel(timeZone: timeZone, updatedAt: updatedAt)) if let appModel = item.toAppModel(timeZone: timeZone, updatedAt: updatedAt) {
result.append(appModel)
}
} }
return result return result
} }
......
...@@ -41,12 +41,16 @@ struct WdtDailySummary: Codable { ...@@ -41,12 +41,16 @@ struct WdtDailySummary: Codable {
case moonsetUtc = "solunar_moonset_utc" case moonsetUtc = "solunar_moonset_utc"
} }
public func toAppModel(timeZone: TimeZone, updatedAt: Date) throws -> DailyWeather { private static let log = Logger(componentName: "WdtDailySummary")
public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> DailyWeather? {
let log = WdtDailySummary.log
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/YYYY" dateFormatter.dateFormat = "MM/dd/YYYY"
dateFormatter.timeZone = timeZone dateFormatter.timeZone = timeZone
guard let date = dateFormatter.date(from: dateLocal) else { guard let date = dateFormatter.date(from: dateLocal) else {
throw WdtWeatherSourceError.dataMergeError("daily.date: \(dateLocal)") log.error("Failed to parse date from: \(dateLocal)")
return nil
} }
var weekDay = WeekDay(rawValue: self.weekDay) var weekDay = WeekDay(rawValue: self.weekDay)
...@@ -56,7 +60,8 @@ struct WdtDailySummary: Codable { ...@@ -56,7 +60,8 @@ struct WdtDailySummary: Codable {
weekDay = WeekDay(grigorianWeekDayNumber: calendar.component(.weekday, from: date)) weekDay = WeekDay(grigorianWeekDayNumber: calendar.component(.weekday, from: date))
} }
guard let weekDayUnwrapped = weekDay else { guard let weekDayUnwrapped = weekDay else {
throw WdtWeatherSourceError.dataMergeError("daily.weekday: \(self.weekDay)") log.error("Couldn't parse week day: \(self.weekDay)")
return nil
} }
var result = DailyWeather(lastTimeUpdated: updatedAt, date: date, timeZone: timeZone, weekDay: weekDayUnwrapped) var result = DailyWeather(lastTimeUpdated: updatedAt, date: date, timeZone: timeZone, weekDay: weekDayUnwrapped)
......
...@@ -34,13 +34,17 @@ struct WdtHourlySummary: Codable { ...@@ -34,13 +34,17 @@ struct WdtHourlySummary: Codable {
case weatherCode = "wx_code" case weatherCode = "wx_code"
} }
public func toAppModel(timeZone: TimeZone, updatedAt: Date) throws -> HourlyWeather { private static let log = Logger(componentName: "WdtHourlySummary")
public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> HourlyWeather? {
let log = WdtHourlySummary.log
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
dateFormatter.timeZone = timeZone dateFormatter.timeZone = timeZone
guard let date = dateFormatter.date(from: self.dateTimeLocal) else { guard let date = dateFormatter.date(from: dateTimeLocal) else {
throw WdtWeatherSourceError.dataMergeError("hourly.date: \(self.dateTimeLocal)") log.error("Failed to parse date from: \(dateTimeLocal)")
return nil
} }
var weekDay = WeekDay(rawValue: self.weekDay) var weekDay = WeekDay(rawValue: self.weekDay)
...@@ -50,7 +54,8 @@ struct WdtHourlySummary: Codable { ...@@ -50,7 +54,8 @@ struct WdtHourlySummary: Codable {
weekDay = WeekDay(grigorianWeekDayNumber: calendar.component(.weekday, from: date)) weekDay = WeekDay(grigorianWeekDayNumber: calendar.component(.weekday, from: date))
} }
guard let weekDayUnwrapped = weekDay else { guard let weekDayUnwrapped = weekDay else {
throw WdtWeatherSourceError.dataMergeError("hourly.weekday: \(self.weekDay)") log.error("Couldn't parse week day: \(self.weekDay)")
return nil
} }
let isDay = dayNight.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() == "day" let isDay = dayNight.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() == "day"
......
...@@ -37,17 +37,17 @@ struct WdtLocation: Codable { ...@@ -37,17 +37,17 @@ struct WdtLocation: Codable {
if let lat = CLLocationDegrees(lat ?? ""), let lon = CLLocationDegrees(lon ?? "") { if let lat = CLLocationDegrees(lat ?? ""), let lon = CLLocationDegrees(lon ?? "") {
coordinates = CLLocationCoordinate2D(latitude: lat, longitude: lon) coordinates = CLLocationCoordinate2D(latitude: lat, longitude: lon)
} }
var today = try surfaceObservation.toAppModel(timeZone: timeZone, updatedAt: updatedAt) var today = surfaceObservation.toAppModel(timeZone: timeZone, updatedAt: updatedAt)
let dailyWeather = try dailySummaries?.toAppModel(timeZone: timeZone, updatedAt: updatedAt) ?? [DailyWeather]() let dailyWeather = try dailySummaries?.toAppModel(timeZone: timeZone, updatedAt: updatedAt) ?? [DailyWeather]()
let hourlyWeather = try hourlySummaries?.toAppModel(timeZone: timeZone, updatedAt: updatedAt) ?? [HourlyWeather]() let hourlyWeather = try hourlySummaries?.toAppModel(timeZone: timeZone, updatedAt: updatedAt) ?? [HourlyWeather]()
if let firstDay = dailyWeather.first { if let firstDay = dailyWeather.first {
today.minTemp = firstDay.minTemp today?.minTemp = firstDay.minTemp
today.maxTemp = firstDay.maxTemp today?.maxTemp = firstDay.maxTemp
today.precipitationProbability = firstDay.precipitationProbability today?.precipitationProbability = firstDay.precipitationProbability
today.sunState = firstDay.sunState today?.sunState = firstDay.sunState
today.moonState = firstDay.moonState today?.moonState = firstDay.moonState
today.moonPhase = firstDay.moonPhase today?.moonPhase = firstDay.moonPhase
} }
return Location(lastTimeUpdated: updatedAt, return Location(lastTimeUpdated: updatedAt,
......
...@@ -40,13 +40,17 @@ struct WdtSurfaceObservation: Codable { ...@@ -40,13 +40,17 @@ struct WdtSurfaceObservation: Codable {
case sunsetLocalTime = "sunset_local" case sunsetLocalTime = "sunset_local"
} }
public func toAppModel(timeZone: TimeZone, updatedAt: Date) throws -> CurrentWeather { private static let log = Logger(componentName: "WdtSurfaceObservation")
public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> CurrentWeather? {
let log = WdtSurfaceObservation.log
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
dateFormatter.timeZone = timeZone dateFormatter.timeZone = timeZone
guard let date = dateFormatter.date(from: self.dateTimeLocal) else { guard let date = dateFormatter.date(from: self.dateTimeLocal) else {
throw WdtWeatherSourceError.dataMergeError("today.date: \(dateTimeLocal)") log.error("failed to parse date from: \(self.dateTimeLocal)")
return nil
} }
var weekDay = WeekDay(rawValue: self.weekDay) var weekDay = WeekDay(rawValue: self.weekDay)
if weekDay == nil { if weekDay == nil {
...@@ -55,7 +59,8 @@ struct WdtSurfaceObservation: Codable { ...@@ -55,7 +59,8 @@ struct WdtSurfaceObservation: Codable {
weekDay = WeekDay(grigorianWeekDayNumber: calendar.component(.weekday, from: date)) weekDay = WeekDay(grigorianWeekDayNumber: calendar.component(.weekday, from: date))
} }
guard let weekDayUnwrapped = weekDay else { guard let weekDayUnwrapped = weekDay else {
throw WdtWeatherSourceError.dataMergeError("today.weekday: \(self.weekDay)") log.error("Couldn't parse weekDay from: \(self.weekDay)")
return nil
} }
let isDay = dayNight.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() == "day" let isDay = dayNight.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() == "day"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment