Commit c0f80491 by Demid Merzlyakov

Models: work in progress.

parent 479ba0f2
......@@ -55,6 +55,7 @@
CEC526FD25E795F700DA58A5 /* WdtWeatherSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC526FC25E795F700DA58A5 /* WdtWeatherSource.swift */; };
CEC5270025E7BACB00DA58A5 /* WdtLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC526FF25E7BACB00DA58A5 /* WdtLocation.swift */; };
CEC5270325E7BB4000DA58A5 /* WdtSurfaceObservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC5270225E7BB4000DA58A5 /* WdtSurfaceObservation.swift */; };
CEC5275D25E8E50B00DA58A5 /* WdtDailySummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC5275C25E8E50B00DA58A5 /* WdtDailySummary.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
......@@ -110,6 +111,7 @@
CEC526FC25E795F700DA58A5 /* WdtWeatherSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WdtWeatherSource.swift; sourceTree = "<group>"; };
CEC526FF25E7BACB00DA58A5 /* WdtLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WdtLocation.swift; sourceTree = "<group>"; };
CEC5270225E7BB4000DA58A5 /* WdtSurfaceObservation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WdtSurfaceObservation.swift; sourceTree = "<group>"; };
CEC5275C25E8E50B00DA58A5 /* WdtDailySummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WdtDailySummary.swift; sourceTree = "<group>"; };
DF826CF4702D9DCCB9A9DD71 /* Pods-1Weather.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-1Weather.release.xcconfig"; path = "Target Support Files/Pods-1Weather/Pods-1Weather.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
......@@ -344,6 +346,7 @@
CEAFF09B25DFC79F00DF4EBF /* WdtWeatherCode.swift */,
CEC526FF25E7BACB00DA58A5 /* WdtLocation.swift */,
CEC5270225E7BB4000DA58A5 /* WdtSurfaceObservation.swift */,
CEC5275C25E8E50B00DA58A5 /* WdtDailySummary.swift */,
);
path = Model;
sourceTree = "<group>";
......@@ -518,6 +521,7 @@
CDE18DCA25D165F100C80ED9 /* UITabBarController+Append.swift in Sources */,
CEC526FA25E7959A00DA58A5 /* WeatherSource.swift in Sources */,
CD822FFE25D6976F00A05501 /* TodayAdCell.swift in Sources */,
CEC5275D25E8E50B00DA58A5 /* WdtDailySummary.swift in Sources */,
CDE18DCD25D1666700C80ED9 /* ForecastCoordinator.swift in Sources */,
CD80917B2578E4A8003541A4 /* UIViewController+Alert.swift in Sources */,
CD17C5F625D15B4400EE884E /* TodayViewController.swift in Sources */,
......
......@@ -32,7 +32,7 @@ public enum WeatherType: String {
case unknown = "unknown"
}
public enum WindDirection: String {
public enum WindDirection: String, Codable {
case north = "N"
case northNorthEast = "NNE"
case northEast = "NE"
......@@ -53,14 +53,14 @@ public enum WindDirection: String {
/// Not everybody uses a 7 day week, but not a lot of people.
public enum WeekDay: Int {
case monday
case tuesday
case wednesday
case thursday
case friday
case saturday
case sunday
public enum WeekDay: String, Codable {
case monday = "Monday"
case tuesday = "Tuesday"
case wednesday = "Wednesday"
case thursday = "Thursday"
case friday = "Friday"
case saturday = "Saturday"
case sunday = "Sunday"
}
public enum CelestialState {
......@@ -69,13 +69,22 @@ public enum CelestialState {
case neverUp
}
public struct Time: CustomStringConvertible {
public struct Time: CustomStringConvertible, Codable {
public let hours: UInt8
public let minutes: UInt8
public var description: String {
var amOrPm = "am"
#if DEBUG
//TODO: REMOVE THIS'
TimeZone
#warning("THIS IS A DEBUG-ONLY PIECE OF CODE! Not even temporary! Remove before making a production build.")
#else
#error("THIS IS A DEBUG-ONLY PIECE OF CODE! Not even temporary! Remove before making a production build.")
#endif
var convertedHours = hours
if convertedHours > 12 {
amOrPm = "pm"
......@@ -86,6 +95,63 @@ public struct Time: CustomStringConvertible {
}
return "\(String(format: "%02d", convertedHours)):\(minutes) \(amOrPm)"
}
public init(from decoder: Decoder) throws {
let valueContainer = try decoder.singleValueContainer()
let value = try valueContainer.decode(String.self).trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
var isAm: Bool?
if value.contains("am") {
isAm = true
}
else if value.contains("pm") {
isAm = false
}
let timeRegEx = try! NSRegularExpression(pattern: "(\\d\\d?):(\\d\\d?)") //it's a correct regexp, otherwise it'd better crash during development.
let allMatches = timeRegEx.matches(in: value, range: NSRangeFromString(value))
let nsValue = value as NSString
guard let match = allMatches.first else {
throw DecodingError.dataCorruptedError(in: valueContainer, debugDescription: "Couldn't parse time info from string \(value).")
}
let parsedHours = UInt8(nsValue.substring(with: match.range(at: 1)))! // we know if will get parsed, because regexp guarantees it's two digits without a sign.
let parsedMinutes = UInt8(nsValue.substring(with: match.range(at: 1)))! // same here
guard parsedMinutes >= 0 && parsedMinutes <= 59 else {
throw DecodingError.dataCorruptedError(in: valueContainer, debugDescription: "Minute value is not acceptible: \(parsedMinutes)")
}
minutes = parsedMinutes
if let isAm = isAm {
guard parsedHours >= 1 && parsedHours <= 12 else {
throw DecodingError.dataCorruptedError(in: valueContainer, debugDescription: "Hour value is not acceptible for a 12h format: \(parsedHours)")
}
if parsedHours == 12 {
if isAm {
hours = 0
}
else {
hours = 12
}
}
else {
if !isAm {
hours = parsedHours + 12
}
}
}
else {
guard parsedHours >= 0 && parsedHours <= 23 else {
throw DecodingError.dataCorruptedError(in: valueContainer, debugDescription: "Hour value is not acceptible for a 24h format: \(parsedHours)")
}
hours = parsedHours
}
}
public func encode(to encoder: Encoder) throws {
encoder.singleValueContainer().encode(self.description)
}
}
public typealias Temperature = Measurement<UnitTemperature>
......
//
// WdtDailySummary.swift
// 1Weather
//
// Created by Demid Merzlyakov on 26.02.2021.
//
import Foundation
public struct WdtDailySummary: Codable {
public var minTempF: Double?
public var maxTempF: Double
public var windSpeedKph: Double?
public var windDirection: WindDirection?
public var weekDay: WeekDay
public var weatherCode: WdtWeatherCode?
public var precipitationProbability: Int?
public var sunriseLocal: Time?
public var sunsetLocal: Time?
// Wdt doesn't return local moonrise / moonset... why? :'(
// TODO: store time / date as Date + NSTimeZone
enum CodingKeys: String, CodingKey {
case minTempF = "min_temp_F"
case maxTempF = "max_temp_F"
case windSpeedKph = "wnd_spd_kph"
case windDirection = "wnd_dir"
case weekDay = "day_of_week"
case weatherCode = "wx_code"
case precipitationProbability = "pop"
}
}
......@@ -15,6 +15,15 @@ public struct WdtLocation: Codable {
public private (set) var country: String?
public private (set) var zipcode: String?
public var sfc_ob: WdtSurfaceObservation
public var
public var surfaceObservation: WdtSurfaceObservation
enum CodingKeys: String, CodingKey {
case lat
case lon
case city
case region
case country
case zipcode
case surfaceObservation = "sfc_ob"
}
}
......@@ -8,5 +8,23 @@
import Foundation
public struct WdtSurfaceObservation: Codable {
public var tempF: Double?
public var apparentTempF: Double?
public var windSpeedKph: Double?
public var windDirection: WindDirection?
public var pressureMb: Double?
public var visibilityFt: Double
public var weekDay: WeekDay?
public var weatherCode: WdtWeatherCode?
enum CodingKeys: String, CodingKey {
case tempF = "temp_F"
case apparentTempF = "apparent_temp_F"
case windSpeedKph = "wnd_spd_kph"
case windDirection = "wnd_dir"
case pressureMb = "press_mb"
case visibilityFt = "visibility_ft"
case weekDay = "day_of_week_local"
case weatherCode = "wx_code"
}
}
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