Commit 76f74ba9 by Demid Merzlyakov

DayTime weather not hardcoded.

parent 83807d43
......@@ -60,6 +60,7 @@
CDE18DD125D166F900C80ED9 /* ForecastViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDE18DD025D166F900C80ED9 /* ForecastViewController.swift */; };
CDE18DD825D16CB200C80ED9 /* NavigationCityButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDE18DD725D16CB200C80ED9 /* NavigationCityButton.swift */; };
CDEE8AD725DA882200C289DE /* PeriodForecastButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDEE8AD625DA882200C289DE /* PeriodForecastButton.swift */; };
CE578FD325F7E89400E8B85D /* DayTimeWeather.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE578FD225F7E89400E8B85D /* DayTimeWeather.swift */; };
CE9D181625ECB8370028D9D7 /* MulticastDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9D181525ECB8370028D9D7 /* MulticastDelegate.swift */; };
CE9D181925ECB9A70028D9D7 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9D181825ECB9A70028D9D7 /* Logger.swift */; };
CEAD00A12577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAD00A02577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift */; };
......@@ -142,6 +143,7 @@
CDE18DD025D166F900C80ED9 /* ForecastViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastViewController.swift; sourceTree = "<group>"; };
CDE18DD725D16CB200C80ED9 /* NavigationCityButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCityButton.swift; sourceTree = "<group>"; };
CDEE8AD625DA882200C289DE /* PeriodForecastButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeriodForecastButton.swift; sourceTree = "<group>"; };
CE578FD225F7E89400E8B85D /* DayTimeWeather.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DayTimeWeather.swift; sourceTree = "<group>"; };
CE9D181525ECB8370028D9D7 /* MulticastDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MulticastDelegate.swift; sourceTree = "<group>"; };
CE9D181825ECB9A70028D9D7 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
CEAD00A02577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StuffThatIsPresentInTheMainProject.swift; sourceTree = "<group>"; };
......@@ -488,6 +490,7 @@
CEAFF08825DFC6B200DF4EBF /* CurrentWeather.swift */,
CEAFF08B25DFC6BC00DF4EBF /* DailyWeather.swift */,
CEAFF08E25DFC6ED00DF4EBF /* HourlyWeather.swift */,
CE578FD225F7E89400E8B85D /* DayTimeWeather.swift */,
);
path = ModelObjects;
sourceTree = "<group>";
......@@ -641,6 +644,7 @@
CEAFF09225DFC71D00DF4EBF /* HelperTypes.swift in Sources */,
CDA5543025EFA13F00A2E08C /* Measurement+String.swift in Sources */,
CE9D181925ECB9A70028D9D7 /* Logger.swift in Sources */,
CE578FD325F7E89400E8B85D /* DayTimeWeather.swift in Sources */,
CEAFF08925DFC6B200DF4EBF /* CurrentWeather.swift in Sources */,
CEC5270325E7BB4000DA58A5 /* WdtSurfaceObservation.swift in Sources */,
CEAFF08C25DFC6BD00DF4EBF /* DailyWeather.swift in Sources */,
......
......@@ -130,7 +130,51 @@ public enum WeekDay: String, Codable {
}
}
public enum DayTime: Int, CaseIterable {
case morning = 7
case noon = 12
case evening = 18
case night = 23
public var localized:String {
switch self {
case .morning:
return "dayTime.morning".localized()
case .noon:
return "dayTime.noon".localized()
case .evening:
return "dayTime.evening".localized()
case .night:
return "dayTime.night".localized()
}
}
/// For a given date (with arbitrary time) in a given time zone returns a date object for canonical time for the given DayTime.
/// Example 1: Given a date 2020-01-01 04:33 UTC, dayTime .noon and timezone UTC+0, it will return 2020-01-01 12-00 UTC.
/// Example 2 (with a non-UTC time zone): given a date 2020-01-01 04:33 UTC, dayTime .noon and timezone UTC-5 it will return 2019-12-31 12 UTC,
/// because in UTC-5 it's still 2019-12-31, so it will return the canonical time for noon within that day.
///
/// The canonical times are:
/// • `.morning`: 7,
/// • `.noon`: 12,
/// • `.evening`: 18,
/// • `.night`: 23
///
/// - Parameters:
/// - dayTime: `DayTime`, for which we need to get the canonical time.
/// - day: A date for which we need to get a canonical time. The time part may be arbitrary as long as it's within the given date (according to the timeZone parameter).
/// - timeZone: TimeZone to use for time calculations.
/// - Returns: A date that corresponds to a canonical time within the day specified by the `day` parameter in a given timeZone
public static func canonicalTime(of dayTime: DayTime, for day: Date, in timeZone: TimeZone) -> Date? {
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = timeZone
return calendar.date(bySettingHour: dayTime.rawValue, minute: 0, second: 0, of: day)
}
public init?(hour: Int) {
self.init(rawValue: hour)
}
}
public enum CelestialState: String, Codable {
case normal = ""
......
//
// DayTimeWeather.swift
// 1Weather
//
// Created by Demid Merzlyakov on 09.03.2021.
//
import Foundation
public struct DayTimeWeather {
public var dayTime: DayTime
public var date: Date
public var timeZone: TimeZone
public var weekDay: WeekDay
public var type: WeatherType = .unknown
public var isDay: Bool
public var temp: Temperature?
public init(dayTime: DayTime, hourly: HourlyWeather) {
self.dayTime = dayTime
self.date = hourly.date
self.timeZone = hourly.timeZone
self.weekDay = hourly.weekDay
self.type = hourly.type
self.isDay = hourly.isDay
self.temp = hourly.temp
}
}
......@@ -42,8 +42,21 @@ public struct Location: CustomStringConvertible {
public var timeZone: TimeZone
public var today: CurrentWeather?
public var daily: [DailyWeather] = [DailyWeather]()
public var hourly: [HourlyWeather] = [HourlyWeather]()
public var daily = [DailyWeather]()
public var hourly = [HourlyWeather]() {
didSet {
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = self.timeZone
dayTimeForecast = hourly.compactMap {
guard let dayTime = DayTime(hour: calendar.component(.hour, from: $0.date)) else {
return nil
}
return DayTimeWeather(dayTime: dayTime, hourly: $0)
}
}
}
public private (set) var dayTimeForecast: [DayTimeWeather] = [DayTimeWeather]()
// MARK: - Derived fields
public var cityId: String {
......
......@@ -27,7 +27,27 @@ class CityDayTimesCell: UITableViewCell {
//Private
@objc private func handleArrowButton() {
#warning("Not implemented!")
//TODO: Implement!
}
public func configure(with location: Location) {
for subview in stackView.subviews {
subview.removeFromSuperview()
}
let maxNumberOfItems = 4
var currentlyShowing = 0
var i = 0
while i < location.dayTimeForecast.count && currentlyShowing < maxNumberOfItems {
let dayTimeWeather = location.dayTimeForecast[i]
i += 1
if dayTimeWeather.date >= Date() {
let view = DayTimeView(dayTimeWeather: dayTimeWeather)
stackView.addArrangedSubview(view)
currentlyShowing += 1
}
}
}
}
......@@ -68,11 +88,6 @@ private extension CityDayTimesCell {
stackView.clipsToBounds = false
contentView.addSubview(stackView)
for (index, dayTime) in DayTime.allCases.enumerated() {
let view = DayTimeView(dayTime: dayTime, withSeparator: index < DayTime.allCases.count - 1)
stackView.addArrangedSubview(view)
}
stackView.snp.makeConstraints { (make) in
make.left.right.equalToSuperview()
make.top.equalTo(headingLabel.snp.bottom).offset(18)
......
......@@ -7,45 +7,32 @@
import UIKit
public enum DayTime: CaseIterable {
case morning
case noon
case evening
case night
var localized:String {
switch self {
case .morning:
return "dayTime.morning".localized()
case .noon:
return "dayTime.noon".localized()
case .evening:
return "dayTime.evening".localized()
case .night:
return "dayTime.night".localized()
}
}
}
class DayTimeView: UIView {
private let dayTimeLabel = UILabel()
private let forecastImageView = UIImageView()
private let tempLabel = UILabel()
private let dayTimeConditionLabel = UILabel()
init(dayTime:DayTime, withSeparator:Bool = false) {
public init(dayTimeWeather:DayTimeWeather, withSeparator:Bool = false) {
super.init(frame: .zero)
prepareView()
if withSeparator {
prepareSeparator()
}
dayTimeLabel.text = dayTime.localized
configure(with: dayTimeWeather)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func configure(with dayTimeWeather:DayTimeWeather) {
dayTimeLabel.text = dayTimeWeather.dayTime.localized
forecastImageView.image = UIImage(named: dayTimeWeather.type.rawValue)
tempLabel.text = dayTimeWeather.temp?.shortString ?? "--"
}
}
//MARK:- Prepare
......@@ -53,21 +40,21 @@ private extension DayTimeView {
func prepareView() {
dayTimeLabel.font = AppFont.SFPro.bold(size: 14)
dayTimeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
dayTimeLabel.text = "dayTime.morning".localized()
dayTimeLabel.text = "--"
addSubview(dayTimeLabel)
forecastImageView.contentMode = .scaleAspectFit
forecastImageView.image = UIImage(named: "partly_cloudy")
forecastImageView.image = nil //TODO: we need a placeholder here?
addSubview(forecastImageView)
tempLabel.font = AppFont.SFPro.bold(size: 18)
tempLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
tempLabel.text = "85°"
tempLabel.text = "--"
addSubview(tempLabel)
dayTimeConditionLabel.font = AppFont.SFPro.regular(size: 14)
dayTimeConditionLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
dayTimeConditionLabel.text = "forecast.clear".localized()
dayTimeConditionLabel.text = "--"
addSubview(dayTimeConditionLabel)
//Constraints
......
......@@ -67,6 +67,7 @@ class TodayCellFactory {
return cell
case .dayTime:
let cell = dequeueReusableCell(type: CityDayTimesCell.self, tableView: tableView, indexPath: indexPath)
cell.configure(with: loc)
return cell
case .sun:
let cell = dequeueReusableCell(type: CitySunCell.self, tableView: tableView, indexPath: indexPath)
......
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