Commit a2242a8e by Demid Merzlyakov

Wdt networking (WIP). Slight model changes.

parent 9319cb56
......@@ -62,7 +62,6 @@
CEAFF08C25DFC6BD00DF4EBF /* DailyWeather.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAFF08B25DFC6BC00DF4EBF /* DailyWeather.swift */; };
CEAFF08F25DFC6ED00DF4EBF /* HourlyWeather.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAFF08E25DFC6ED00DF4EBF /* HourlyWeather.swift */; };
CEAFF09225DFC71D00DF4EBF /* HelperTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAFF09125DFC71D00DF4EBF /* HelperTypes.swift */; };
CEAFF09C25DFC79F00DF4EBF /* WdtWeatherCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAFF09B25DFC79F00DF4EBF /* WdtWeatherCode.swift */; };
CEAFF0A325E0FF0800DF4EBF /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAFF0A225E0FF0800DF4EBF /* LocationManager.swift */; };
CEC526FA25E7959A00DA58A5 /* WeatherSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC526F925E7959A00DA58A5 /* WeatherSource.swift */; };
CEC526FD25E795F700DA58A5 /* WdtWeatherSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC526FC25E795F700DA58A5 /* WdtWeatherSource.swift */; };
......@@ -70,6 +69,11 @@
CEC5270325E7BB4000DA58A5 /* WdtSurfaceObservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC5270225E7BB4000DA58A5 /* WdtSurfaceObservation.swift */; };
CEC5275D25E8E50B00DA58A5 /* WdtDailySummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC5275C25E8E50B00DA58A5 /* WdtDailySummary.swift */; };
CEC5276025E92DDA00DA58A5 /* WdtHourlySummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC5275F25E92DDA00DA58A5 /* WdtHourlySummary.swift */; };
CEDE4E8225EEFD56007457E9 /* WdtWeatherCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE4E7E25EEFD56007457E9 /* WdtWeatherCode.swift */; };
CEDE4E8325EEFD56007457E9 /* WdtLocationResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE4E7F25EEFD56007457E9 /* WdtLocationResponse.swift */; };
CEDE4E8425EEFD56007457E9 /* WdtDailySummariesArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE4E8025EEFD56007457E9 /* WdtDailySummariesArray.swift */; };
CEDE4E8525EEFD56007457E9 /* WdtHourlySummariesArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE4E8125EEFD56007457E9 /* WdtHourlySummariesArray.swift */; };
CEDE4E8925EEFFEF007457E9 /* WdtDayNight.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE4E8825EEFFEF007457E9 /* WdtDayNight.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
......@@ -132,7 +136,6 @@
CEAFF08B25DFC6BC00DF4EBF /* DailyWeather.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyWeather.swift; sourceTree = "<group>"; };
CEAFF08E25DFC6ED00DF4EBF /* HourlyWeather.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HourlyWeather.swift; sourceTree = "<group>"; };
CEAFF09125DFC71D00DF4EBF /* HelperTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelperTypes.swift; sourceTree = "<group>"; };
CEAFF09B25DFC79F00DF4EBF /* WdtWeatherCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WdtWeatherCode.swift; sourceTree = "<group>"; };
CEAFF0A225E0FF0800DF4EBF /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = "<group>"; };
CEC526F925E7959A00DA58A5 /* WeatherSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherSource.swift; sourceTree = "<group>"; };
CEC526FC25E795F700DA58A5 /* WdtWeatherSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WdtWeatherSource.swift; sourceTree = "<group>"; };
......@@ -140,6 +143,11 @@
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>"; };
CEC5275F25E92DDA00DA58A5 /* WdtHourlySummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WdtHourlySummary.swift; sourceTree = "<group>"; };
CEDE4E7E25EEFD56007457E9 /* WdtWeatherCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WdtWeatherCode.swift; sourceTree = "<group>"; };
CEDE4E7F25EEFD56007457E9 /* WdtLocationResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WdtLocationResponse.swift; sourceTree = "<group>"; };
CEDE4E8025EEFD56007457E9 /* WdtDailySummariesArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WdtDailySummariesArray.swift; sourceTree = "<group>"; };
CEDE4E8125EEFD56007457E9 /* WdtHourlySummariesArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WdtHourlySummariesArray.swift; sourceTree = "<group>"; };
CEDE4E8825EEFFEF007457E9 /* WdtDayNight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WdtDayNight.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 */
......@@ -432,7 +440,7 @@
CEAFF09A25DFC79100DF4EBF /* Model */ = {
isa = PBXGroup;
children = (
CEAFF09B25DFC79F00DF4EBF /* WdtWeatherCode.swift */,
CEDE4E7D25EEFD56007457E9 /* HelperObjects */,
CEC526FF25E7BACB00DA58A5 /* WdtLocation.swift */,
CEC5270225E7BB4000DA58A5 /* WdtSurfaceObservation.swift */,
CEC5275C25E8E50B00DA58A5 /* WdtDailySummary.swift */,
......@@ -453,6 +461,18 @@
path = ModelObjects;
sourceTree = "<group>";
};
CEDE4E7D25EEFD56007457E9 /* HelperObjects */ = {
isa = PBXGroup;
children = (
CEDE4E7F25EEFD56007457E9 /* WdtLocationResponse.swift */,
CEDE4E7E25EEFD56007457E9 /* WdtWeatherCode.swift */,
CEDE4E8025EEFD56007457E9 /* WdtDailySummariesArray.swift */,
CEDE4E8125EEFD56007457E9 /* WdtHourlySummariesArray.swift */,
CEDE4E8825EEFFEF007457E9 /* WdtDayNight.swift */,
);
path = HelperObjects;
sourceTree = "<group>";
};
DBFD169AA2AA6A3CB5B68BB5 /* Frameworks */ = {
isa = PBXGroup;
children = (
......@@ -578,7 +598,6 @@
CD82300325D69DE400A05501 /* CityConditionsCell.swift in Sources */,
CEC526FD25E795F700DA58A5 /* WdtWeatherSource.swift in Sources */,
CEAFF09225DFC71D00DF4EBF /* HelperTypes.swift in Sources */,
CEAFF09C25DFC79F00DF4EBF /* WdtWeatherCode.swift in Sources */,
CE9D181925ECB9A70028D9D7 /* Logger.swift in Sources */,
CEAFF08925DFC6B200DF4EBF /* CurrentWeather.swift in Sources */,
CEC5270325E7BB4000DA58A5 /* WdtSurfaceObservation.swift in Sources */,
......@@ -600,13 +619,17 @@
CD17C60225D15C8500EE884E /* CoordinatorProtocol.swift in Sources */,
CD17C5FF25D15B7C00EE884E /* TodayCoordinator.swift in Sources */,
CD822FF525D6817000A05501 /* CityForecastCell.swift in Sources */,
CEDE4E8525EEFD56007457E9 /* WdtHourlySummariesArray.swift in Sources */,
CDC6125725E7AB1A00188DA7 /* CityAirQualityCell.swift in Sources */,
CD6B3036257262C2004B34B3 /* UIColor+Highlight.swift in Sources */,
CEDE4E8425EEFD56007457E9 /* WdtDailySummariesArray.swift in Sources */,
CDEE8AD725DA882200C289DE /* PeriodForecastButton.swift in Sources */,
CDE18DD125D166F900C80ED9 /* ForecastViewController.swift in Sources */,
CD39F2F525DE9571009FE398 /* ArrowButton.swift in Sources */,
CEDE4E8325EEFD56007457E9 /* WdtLocationResponse.swift in Sources */,
CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */,
CD86246925E672A20097F3FB /* PrecipButton.swift in Sources */,
CEDE4E8225EEFD56007457E9 /* WdtWeatherCode.swift in Sources */,
CE9D181625ECB8370028D9D7 /* MulticastDelegate.swift in Sources */,
CD82300A25D6B2AF00A05501 /* AppTabBarController.swift in Sources */,
CDC6126225E8DAB800188DA7 /* CityMoonCell.swift in Sources */,
......@@ -633,6 +656,7 @@
CD86246C25E6826A0097F3FB /* InnerShadowLayer.swift in Sources */,
CEAFF0A325E0FF0800DF4EBF /* LocationManager.swift in Sources */,
CEAD00A12577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift in Sources */,
CEDE4E8925EEFFEF007457E9 /* WdtDayNight.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -12,6 +12,7 @@ public struct CurrentWeather {
public var timeZone: TimeZone
public var weekDay: WeekDay
public var type: WeatherType = .unknown
public var isDay: Bool
public var minTemp: Temperature?
public var maxTemp: Temperature?
......@@ -31,4 +32,5 @@ public struct CurrentWeather {
public var moonrise: Time?
public var moonset: Time?
public var moonState: CelestialState = .normal
public var moonPhase: MoonPhase = .unknown
}
......@@ -25,4 +25,5 @@ public struct DailyWeather {
public var moonrise: Date
public var moonset: Date
public var moonState: CelestialState = .normal
public var moonPhase: MoonPhase = .unknown
}
......@@ -63,10 +63,24 @@ public enum WeekDay: String, Codable {
case sunday = "Sunday"
}
public enum CelestialState {
case normal
case alwaysUp
case neverUp
public enum CelestialState: String, Codable {
case normal = ""
case alwaysUp = "always_up"
case neverUp = "never_up"
}
public enum MoonPhase: String, Codable {
case newMoon = "New Moon"
case waxingCrescentMoon = "Waxing Crescent Moon"
case quarterMoon = "Quarter Moon"
case waxingGibbousMoon = "Waxing Gibbous Moon"
case fullMoon = "Full Moon"
case waningGibbousMoon = "Waning Gibbous Moon"
case lastQuarterMoon = "Last Quarter Moon"
case waningCrescentMoon = "Waning Crescent Moon"
case unknown = "unknown"
}
public struct Time: CustomStringConvertible, Codable {
......
......@@ -12,9 +12,11 @@ public struct HourlyWeather {
public var timeZone: TimeZone
public var weekDay: WeekDay
public var type: WeatherType = .unknown
public var isDay: Bool
public var temp: Temperature?
public var apparentTemp: Temperature?
public var minTemp: Temperature?
public var maxTemp: Temperature?
public var windSpeed: WindSpeed?
public var windDirection: WindDirection?
public var precipitationProbability: Percent?
......
......@@ -10,7 +10,7 @@ import CoreLocation
public struct Location: CustomStringConvertible, Equatable {
// MARK: - Data fields
public var coordinates: CLLocation?
public var coordinates: CLLocationCoordinate2D?
public var imageName = "ny_bridge" //we'll possibly need to switch to URL
public var countryCode: String?
......@@ -18,6 +18,7 @@ public struct Location: CustomStringConvertible, Equatable {
public var region: String? // also, state
public var cityName: String?
public var nickname: String? // nickname given to this location by the user
public var zip: String?
public var fipsCode: String?
......@@ -31,7 +32,12 @@ public struct Location: CustomStringConvertible, Equatable {
}
public var description: String {
return "\(cityId) (\(coordinates?.description ?? "no coordinates"))"
if let coordinates = self.coordinates {
return String(format: "%@ (%.3f, %.3f)", cityId, coordinates.latitude, coordinates.longitude)
}
else {
return "\(cityId) (no coordinates)"
}
}
public static func == (lhs: Location, rhs: Location) -> Bool {
......
//
// WdtDailySummariesArray.swift
// iOS_Test_App_2
//
// Created by Demid Merzlyakov on 03.03.2021.
// Copyright © 2021 Dynamix Software. All rights reserved.
//
import Foundation
/// Needed for XMLCoder to decode the array with the right key name
struct WdtDailySummariesArray: Codable {
let items: [WdtDailySummary]
private enum CodingKeys: String, CodingKey {
/// This is actually a key that will be used for daily_summaries individual elements.
case items = "daily_summary"
}
}
//
// WdtDayNight.swift
// 1Weather
//
// Created by Demid Merzlyakov on 03.03.2021.
//
import Foundation
enum WdtDayNight: String, Codable {
case day = "day"
case night = "night"
}
//
// WdtHourlySummariesArray.swift
// iOS_Test_App_2
//
// Created by Demid Merzlyakov on 03.03.2021.
// Copyright © 2021 Dynamix Software. All rights reserved.
//
import Foundation
/// Needed for XMLCoder to decode the array with the right key name
struct WdtHourlySummariesArray: Codable {
let items: [WdtHourlySummary]
private enum CodingKeys: String, CodingKey {
/// This is actually a key that will be used for hourly_summaries individual elements.
case items = "hourly_summary"
}
}
//
// WdtLocationArray.swift
// iOS_Test_App_2
//
// Created by Demid Merzlyakov on 03.03.2021.
// Copyright © 2021 Dynamix Software. All rights reserved.
//
import Foundation
/// Needed for XMLCoder to decode the array with the right key name
struct WdtLocationResponse: Codable {
public let locations: [WdtLocation]
private enum CodingKeys: String, CodingKey {
/// This is actually a key that will be used for location individual elements.
case locations = "location"
}
}
......@@ -7,7 +7,7 @@
import Foundation
public enum WdtWeatherCode: String, Codable {
enum WdtWeatherCode: String, Codable {
// "ic_static_smoke"
case smoke = "3"
// "ic_static_hazy"
......
......@@ -7,7 +7,8 @@
import Foundation
public struct WdtDailySummary: Codable {
struct WdtDailySummary: Codable {
public var dateLocal: String
public var minTempF: Double?
public var maxTempF: Double
public var windSpeedKph: Double?
......@@ -17,11 +18,14 @@ public struct WdtDailySummary: Codable {
public var precipitationProbability: Int?
public var sunriseUtc: String?
public var sunsetUtc: String?
public var sunState: CelestialState? // if nil, then normal
public var moonriseUtc: String?
public var moonsetUtc: String?
public var date: String?
public var moonState: CelestialState? // if nil then normal
public var moonPhase: MoonPhase? //if nil then unknown
enum CodingKeys: String, CodingKey {
private enum CodingKeys: String, CodingKey {
case dateLocal = "summary_date"
case minTempF = "min_temp_F"
case maxTempF = "max_temp_F"
case windSpeedKph = "wnd_spd_kph"
......@@ -33,6 +37,5 @@ public struct WdtDailySummary: Codable {
case sunsetUtc = "solunar_sunset_utc"
case moonriseUtc = "solunar_moonrise_utc"
case moonsetUtc = "solunar_moonset_utc"
case date = "summary_date"
}
}
......@@ -8,6 +8,27 @@
import Foundation
struct WdtHourlySummary: Codable {
// TODO: gotta parse date from local + current date at the time of the request.
public var dateTimeLocal: String
public var tempF: Double?
public var apparentTempF: Double?
public var windSpeedKph: Double?
public var windDirection: WindDirection?
public var humidity: Percent?
public var weekDay: WeekDay
public var dayNight: WdtDayNight
public var precipitationProbability: Int?
public var weatherCode: WdtWeatherCode?
private enum CodingKeys: String, CodingKey {
case dateTimeLocal = "time_local"
case tempF = "temp_F"
case apparentTempF = "apparent_temp_F"
case windSpeedKph = "wnd_spd_kph"
case windDirection = "wnd_dir"
case humidity = "rh_pct"
case weekDay = "day_of_week_local"
case dayNight = "day_night"
case precipitationProbability = "pop"
case weatherCode = "wx_code"
}
}
......@@ -7,7 +7,7 @@
import Foundation
public struct WdtLocation: Codable {
struct WdtLocation: Codable {
public private (set) var lat: String?
public private (set) var lon: String?
public private (set) var city: String?
......@@ -16,8 +16,10 @@ public struct WdtLocation: Codable {
public private (set) var zipcode: String?
public var surfaceObservation: WdtSurfaceObservation
public var dailySummaries: WdtDailySummariesArray?
public var hourlySummaries: WdtHourlySummariesArray?
enum CodingKeys: String, CodingKey {
private enum CodingKeys: String, CodingKey {
case lat
case lon
case city
......@@ -25,5 +27,7 @@ public struct WdtLocation: Codable {
case country
case zipcode
case surfaceObservation = "sfc_ob"
case dailySummaries = "daily_summaries"
case hourlySummaries = "hourly_summaries"
}
}
......@@ -7,26 +7,34 @@
import Foundation
public struct WdtSurfaceObservation: Codable {
struct WdtSurfaceObservation: Codable {
public var dateTimeLocal: String
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 visibilityFt: Double?
public var humidity: Percent?
public var weekDay: WeekDay?
public var dayNight: WdtDayNight
public var weatherCode: WdtWeatherCode?
public var observationLocalTime: String?
public var sunriseLocalTime: String?
public var sunsetLocalTime: String?
enum CodingKeys: String, CodingKey {
private enum CodingKeys: String, CodingKey {
case dateTimeLocal = "ob_time"
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 humidity = "rh_pct"
case weekDay = "day_of_week_local"
case dayNight = "day_night"
case weatherCode = "wx_code"
case observationLocalTime = "ob_time"
case sunriseLocalTime = "sunrise_local"
case sunsetLocalTime = "sunset_local"
}
}
......@@ -6,12 +6,63 @@
//
import Foundation
import CoreLocation
import XMLCoder
public enum WdtWeatherSourceError: Error {
case badUrl
case networkError(Error?)
case badServerResponse(Error?)
}
public class WdtWeatherSource: WeatherSource {
static let updateUrlMega = "https://1weather.onelouder.com/feeds/onelouder/mega.php"
static let updateUrlMicro = "https://1weather.onelouder.com/feeds/onelouder2/fm.php"
private let log = Logger(componentName: "WdtWeatherSource")
private static let updateUrlMega = "https://1weather.onelouder.com/feeds/onelouder/mega.php"
private static let updateUrlMicro = "https://1weather.onelouder.com/feeds/onelouder2/fm.php"
public func updateWeather(for location: Location, completion: (Location) -> ()) {
public func updateWeather(for location: Location, completion: @escaping WeatherSourceCompletion) {
log.debug("Start update.")
guard var urlComponents = URLComponents(string: WdtWeatherSource.updateUrlMega) else {
assertionFailure("Should never happen. The URL should be correct.")
return
}
var queryParameters = [String: String]()
if let coordinates = location.coordinates {
queryParameters["LAT"] = String(format: "%.5f", coordinates.latitude)
queryParameters["LON"] = String(format: "%.5f", coordinates.longitude)
}
else {
queryParameters["ZIP"] = location.zip
queryParameters["CITY"] = location.cityName
queryParameters["STATE"] = location.region
queryParameters["COUNTRY"] = location.countryName
}
queryParameters["UNITS"] = "all"
urlComponents.queryItems = queryParameters.map { URLQueryItem(name: $0, value: $1) }
guard let url = urlComponents.url else {
completion(nil, WdtWeatherSourceError.badUrl)
return
}
let urlSession = URLSession.shared
let dataTask = urlSession.dataTask(with: url) { (data, reponse, error) in
guard let data = data else {
completion(nil, WdtWeatherSourceError.networkError(error))
return
}
let decoder = XMLDecoder()
do {
let locationResponse = try decoder.decode(WdtLocationResponse.self, from: data)
//TODO: convert to app model.
}
catch {
completion(nil, WdtWeatherSourceError.badServerResponse(error))
}
}
dataTask.resume()
}
}
......@@ -7,8 +7,8 @@
import Foundation
public typealias WeatherSourceCompletion = (Location) -> ()
public typealias WeatherSourceCompletion = (Location?, Error?) -> ()
public protocol WeatherSource {
func updateWeather(for location: Location, completion: WeatherSourceCompletion)
func updateWeather(for location: Location, completion: @escaping WeatherSourceCompletion)
}
......@@ -6,6 +6,7 @@
//
import UIKit
import CoreLocation
private enum TodayTableCell {
case forecast
......@@ -35,6 +36,19 @@ class TodayViewController: UIViewController {
prepareViewController()
prepareNavigationBar()
prepareTableView()
#if DEBUG
//TODO: REMOVE THIS'
let source = WdtWeatherSource()
let coordinates = CLLocationCoordinate2D(latitude: 39.867, longitude: 75.233)
let location = Location(coordinates: coordinates)
source.updateWeather(for: location) { (location, error) in
print("Error: \(error)")
}
#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
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
......
import Foundation
import UIKit
import XMLCoder
let a: CGFloat = 169.5
let b: CGFloat = 100
var points = [CGPoint]()
let tValues = stride(from: -0, to: .pi, by: 0.1).map{$0}
public struct WdtLocation: Codable {
public private (set) var lat: String?
public private (set) var lon: String?
public private (set) var city: String?
public private (set) var region: String?
public private (set) var country: String?
public private (set) var zipcode: String?
public var dailySummaries: [WdtDailySummary]
enum CodingKeys: String, CodingKey {
case lat
case lon
case city
case region
case country
case zipcode
case dailySummaries = "daily_summaries"
}
}
for t in tValues {
let x = a * cos(CGFloat(t)) + a
let y = b * sin(CGFloat(t))
points.append(CGPoint(x: x, y: y))
public struct WdtDailySummary: Codable {
public var minTempF: Double?
public var maxTempF: Double
public var windSpeedKph: Double?
public var precipitationProbability: Int?
public var sunriseUtc: String?
public var sunsetUtc: String?
public var moonriseUtc: String?
public var moonsetUtc: String?
public var date: String?
enum CodingKeys: String, CodingKey {
case minTempF = "min_temp_F"
case maxTempF = "max_temp_F"
case windSpeedKph = "wnd_spd_kph"
case precipitationProbability = "pop"
case sunriseUtc = "solunar_sunrise_utc"
case sunsetUtc = "solunar_sunset_utc"
case moonriseUtc = "solunar_moonrise_utc"
case moonsetUtc = "solunar_moonset_utc"
case date = "summary_date"
}
}
print(points)
let xml = """
<!-- https://1weather.onelouder.com/feeds/onelouder/mega.php?LAT=39.95&LON=-75.16&UNITS=all -->
<!-- Philadelphia mega -->
<locations>
<units>all</units>
<language>en</language>
<q />
<location lat="39.95" lon="-75.16" city="Philadelphia" region="PA" country="United States of America" zipcode="19099">
<sfc_ob>
<stn_lat>39.867</stn_lat>
<stn_lon>-75.233</stn_lon>
<ob_time>2021-02-26 04:54:00</ob_time>
<day_of_week_local>Friday</day_of_week_local>
<temp_C>3</temp_C>
<temp_F>37</temp_F>
<dewp_F>21</dewp_F>
<dewp_C>-6</dewp_C>
<rh_pct>52</rh_pct>
<apparent_temp_F>32</apparent_temp_F>
<apparent_temp_C>0</apparent_temp_C>
<wnd_dir>N</wnd_dir>
<wnd_spd_mph>6</wnd_spd_mph>
<wnd_spd_kph>9</wnd_spd_kph>
<press_in>30.36</press_in>
<press_mb>1028.2</press_mb>
<pressure_change>Rising</pressure_change>
<wx>Cloudy</wx>
<wx_code>104</wx_code>
<cld_cover>Cloudy</cld_cover>
<day_night>night</day_night>
<visibility_ft>52800</visibility_ft>
<visibility_m>16093</visibility_m>
<moon_phase>Waxing Gibbous Moon</moon_phase>
<sunrise_local>06:36 am</sunrise_local>
<sunset_local>05:50 pm</sunset_local>
<precip_1hr_mm />
<precip_24hr_mm />
<precip_1hr_in />
<precip_24hr_in />
</sfc_ob>
<daily_summaries>
<daily_summary>
<summary_date>2/26/2021</summary_date>
<day_of_week>Friday</day_of_week>
<max_temp_F>46</max_temp_F>
<max_temp_C>8</max_temp_C>
<min_temp_F>32</min_temp_F>
<min_temp_C>0</min_temp_C>
<wnd_spd_mph>4</wnd_spd_mph>
<wnd_spd_kph>6</wnd_spd_kph>
<wnd_gust_mph>10</wnd_gust_mph>
<wnd_gust_kph>17</wnd_gust_kph>
<wnd_dir>SE</wnd_dir>
<pop>20</pop>
<wx>Partly cloudy</wx>
<wx_code>102</wx_code>
<text_description>Partly cloudy</text_description>
<sunrise_local>06:36 am</sunrise_local>
<sunset_local>05:50 pm</sunset_local>
<moon_phase>Waxing Gibbous Moon</moon_phase>
<early_morning_min_temp_F>32</early_morning_min_temp_F>
<early_morning_min_temp_C>0</early_morning_min_temp_C>
<early_morning_mode_wx>Mostly clear</early_morning_mode_wx>
<early_morning_pop>0</early_morning_pop>
<overnight_min_temp_F>37</overnight_min_temp_F>
<overnight_min_temp_C>3</overnight_min_temp_C>
<overnight_mode_wx>Partly cloudy</overnight_mode_wx>
<overnight_pop>100</overnight_pop>
<solunar_sunrise_utc>2021-02-26 11:37:00</solunar_sunrise_utc>
<solunar_sunset_utc>2021-02-26 22:49:00</solunar_sunset_utc>
<solunar_sun_state />
<solunar_moonrise_utc>2021-02-26 22:08:00</solunar_moonrise_utc>
<solunar_moonset_utc>2021-02-26 11:36:00</solunar_moonset_utc>
<solunar_moon_state />
</daily_summary>
</daily_summaries>
</location>
</locations>
"""
let dailyXml = """
<daily_summary>
<summary_date>2/26/2021</summary_date>
<day_of_week>Friday</day_of_week>
<max_temp_F>46</max_temp_F>
<max_temp_C>8</max_temp_C>
<min_temp_F>32</min_temp_F>
<min_temp_C>0</min_temp_C>
<wnd_spd_mph>4</wnd_spd_mph>
<wnd_spd_kph>6</wnd_spd_kph>
<wnd_gust_mph>10</wnd_gust_mph>
<wnd_gust_kph>17</wnd_gust_kph>
<wnd_dir>SE</wnd_dir>
<pop>20</pop>
<wx>Partly cloudy</wx>
<wx_code>102</wx_code>
<text_description>Partly cloudy</text_description>
<sunrise_local>06:36 am</sunrise_local>
<sunset_local>05:50 pm</sunset_local>
<moon_phase>Waxing Gibbous Moon</moon_phase>
<early_morning_min_temp_F>32</early_morning_min_temp_F>
<early_morning_min_temp_C>0</early_morning_min_temp_C>
<early_morning_mode_wx>Mostly clear</early_morning_mode_wx>
<early_morning_pop>0</early_morning_pop>
<overnight_min_temp_F>37</overnight_min_temp_F>
<overnight_min_temp_C>3</overnight_min_temp_C>
<overnight_mode_wx>Partly cloudy</overnight_mode_wx>
<overnight_pop>100</overnight_pop>
<solunar_sunrise_utc>2021-02-26 11:37:00</solunar_sunrise_utc>
<solunar_sunset_utc>2021-02-26 22:49:00</solunar_sunset_utc>
<solunar_sun_state />
<solunar_moonrise_utc>2021-02-26 22:08:00</solunar_moonrise_utc>
<solunar_moonset_utc>2021-02-26 11:36:00</solunar_moonset_utc>
<solunar_moon_state />
</daily_summary>
"""
let decoder = XMLDecoder()
let data = xml.data(using: .utf8)!
let dataDaily = dailyXml.data(using: .utf8)!
let path = UIBezierPath()
for index in 0..<points.count {
if index == 0 {
path.move(to: points[index])
continue
do {
let allLocations = try decoder.decode([WdtLocation].self, from: data)
if let location = allLocations.first {
print("\(location.dailySummaries)")
}
path.addLine(to: points[index])
let daily = try decoder.decode(WdtDailySummary.self, from: dataDaily)
}
catch {
print("Error: \(error)")
}
print("Noe daily...")
do {
let daily = try decoder.decode(WdtDailySummary.self, from: dataDaily)
}
catch {
print("Error: \(error)")
}
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