Commit 6e2ff6c8 by Demid Merzlyakov

Skeleton for showing one alert.

parent 17daef8a
......@@ -14,6 +14,9 @@
87C1721025FF874B00DA3464 /* PartialLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87C1720F25FF874B00DA3464 /* PartialLocation.swift */; };
87C1724925FF94F400DA3464 /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87C1724825FF94F400DA3464 /* ConfigManager.swift */; };
87D81582262EFC9B0015A6D1 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D81581262EFC9A0015A6D1 /* Notifications.swift */; };
87D815852636CFFE0015A6D1 /* NWSAlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D815842636CFFD0015A6D1 /* NWSAlertViewController.swift */; };
87D815AA2636D5E60015A6D1 /* NWSAlertCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D815A92636D5E60015A6D1 /* NWSAlertCoordinator.swift */; };
87D815AC2636D61D0015A6D1 /* NWSAlertViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D815AB2636D61D0015A6D1 /* NWSAlertViewModel.swift */; };
CD1237C3255D5C5900C98139 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237C2255D5C5900C98139 /* AppDelegate.swift */; };
CD1237CC255D5C5C00C98139 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD1237CB255D5C5C00C98139 /* Assets.xcassets */; };
CD1237F1255D83C500C98139 /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237F0255D83C500C98139 /* UIColor+Hex.swift */; };
......@@ -252,6 +255,9 @@
87C1720F25FF874B00DA3464 /* PartialLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartialLocation.swift; sourceTree = "<group>"; };
87C1724825FF94F400DA3464 /* ConfigManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigManager.swift; sourceTree = "<group>"; };
87D81581262EFC9A0015A6D1 /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
87D815842636CFFD0015A6D1 /* NWSAlertViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NWSAlertViewController.swift; sourceTree = "<group>"; };
87D815A92636D5E60015A6D1 /* NWSAlertCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NWSAlertCoordinator.swift; sourceTree = "<group>"; };
87D815AB2636D61D0015A6D1 /* NWSAlertViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NWSAlertViewModel.swift; sourceTree = "<group>"; };
C8C576F6184B547435CFF0F3 /* Pods-1Weather.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-1Weather.debug.xcconfig"; path = "Target Support Files/Pods-1Weather/Pods-1Weather.debug.xcconfig"; sourceTree = "<group>"; };
CD1237BF255D5C5900C98139 /* 1Weather.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 1Weather.app; sourceTree = BUILT_PRODUCTS_DIR; };
CD1237C2255D5C5900C98139 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
......@@ -513,6 +519,14 @@
path = Weather;
sourceTree = "<group>";
};
87D815832636CFED0015A6D1 /* NWSAlert */ = {
isa = PBXGroup;
children = (
87D815842636CFFD0015A6D1 /* NWSAlertViewController.swift */,
);
path = NWSAlert;
sourceTree = "<group>";
};
CD0A2CC325FA5857006148A4 /* ForecastTimePeriod */ = {
isa = PBXGroup;
children = (
......@@ -619,6 +633,7 @@
CD866A75260F77C500E96A5C /* SettingsDetailsCoordinator.swift */,
CDF9BF8D26133D050037847D /* LocationSearchCoordinator.swift */,
CE0457942632B3F900B3C19A /* NotificationsCoordinator.swift */,
87D815A92636D5E60015A6D1 /* NWSAlertCoordinator.swift */,
);
path = Coordinators;
sourceTree = "<group>";
......@@ -722,6 +737,7 @@
CD37D3F5260DF5BA002669D6 /* SettingsViewModel.swift */,
CD866A6E260F67F200E96A5C /* SettingsDetailsViewModel.swift */,
CE04578F2632B3BC00B3C19A /* NotificationsViewModel.swift */,
87D815AB2636D61D0015A6D1 /* NWSAlertViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
......@@ -729,6 +745,7 @@
CD6B3038257267E2004B34B3 /* View controllers */ = {
isa = PBXGroup;
children = (
87D815832636CFED0015A6D1 /* NWSAlert */,
CE0457912632B3D000B3C19A /* Notifications */,
CE578FE025FB415E00E8B85D /* Locations */,
CD17C5F425D15B3400EE884E /* Today */,
......@@ -1556,6 +1573,7 @@
CD15DB3D25DA6C5100024727 /* ForecastTimePeriodControl.swift in Sources */,
CD1237F1255D83C500C98139 /* UIColor+Hex.swift in Sources */,
CDD0F1EE25725BCF00CF5017 /* ThemeManager.swift in Sources */,
87D815852636CFFE0015A6D1 /* NWSAlertViewController.swift in Sources */,
CD1237F4255D889F00C98139 /* GradientView.swift in Sources */,
CD37D3EF260DF4E6002669D6 /* SettingsViewController.swift in Sources */,
CE6BE4942634170800626822 /* USStateCode.swift in Sources */,
......@@ -1627,6 +1645,7 @@
CE9F01C1261B3776009BA500 /* CoreDataUtils.swift in Sources */,
CDC6126225E8DAB800188DA7 /* MoonPhaseCell.swift in Sources */,
CD37D3D6260C93B3002669D6 /* MenuCellFactory.swift in Sources */,
87D815AC2636D61D0015A6D1 /* NWSAlertViewModel.swift in Sources */,
CD37D3FA260DF714002669D6 /* SettingsThemeCell.swift in Sources */,
CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */,
CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */,
......@@ -1642,6 +1661,7 @@
CEE0A179262FA9650044C257 /* DelayedSaveStorage.swift in Sources */,
CE0456242629C04C003D252B /* NWSAlertsManager.swift in Sources */,
CE8962AB26175DF500CA274A /* CorePollutant.swift in Sources */,
87D815AA2636D5E60015A6D1 /* NWSAlertCoordinator.swift in Sources */,
CEC5276025E92DDA00DA58A5 /* WdtHourlySummary.swift in Sources */,
CDE18DCA25D165F100C80ED9 /* UITabBarController+Append.swift in Sources */,
CE8962AF26175DF500CA274A /* CoreDailyWeather.swift in Sources */,
......
//
// NWSAlertCoordinator.swift
// 1Weather
//
// Created by Demid Merzlyakov on 26.04.2021.
//
import UIKit
class NWSAlertCoordinator: Coordinator {
private let parentViewController:UIViewController
public var childCoordinators = [Coordinator]()
public var parentCoordinator:Coordinator?
private let alert: NWSAlert
private let alertManager: NWSAlertsManager
init(parentViewController:UIViewController, alert: NWSAlert, alertManager: NWSAlertsManager) {
self.parentViewController = parentViewController
self.alert = alert
self.alertManager = alertManager
}
func start() {
let viewModel = NWSAlertViewModel(alert: alert, alertsManager: alertManager)
let viewController = NWSAlertViewController(coordinator: self, viewModel: viewModel)
let navigationController = UINavigationController(rootViewController: viewController)
self.parentViewController.present(navigationController, animated: true)
}
func viewControllerDidEnd(controller:UIViewController) {
parentCoordinator?.childDidFinish(child: self)
}
}
......@@ -10,7 +10,6 @@ import UIKit
class NotificationsCoordinator: Coordinator {
private let parentViewController:UIViewController
public var childCoordinators = [Coordinator]()
public var parentCoordinator: Coordinator?
......@@ -24,9 +23,13 @@ class NotificationsCoordinator: Coordinator {
self.parentViewController.present(navigationController, animated: true)
}
public func openNWSAlert() {
#warning("Not implemented!")
//TODO: Implement!
public func open(nwsAlert: NWSAlert) {
guard let currentlyShownViewController = self.parentViewController.presentedViewController else {
return
}
let coordinator = NWSAlertCoordinator(parentViewController: currentlyShownViewController, alert: nwsAlert, alertManager: LocationManager.shared.nwsAlertsManager)
childCoordinators.append(coordinator)
coordinator.start()
}
func viewControllerDidEnd(controller: UIViewController) {
......
......@@ -166,7 +166,7 @@ public class LocationManager {
self.storage = storage
self.deviceLocationMonitor.delegate = self
self.nwsAlertsManager.delegate = self
self.nwsAlertsManager.delegates.add(delegate: self)
storage.load { [weak self] (locations, selectedIndex, error) in
DispatchQueue.main.async {
......
......@@ -21,7 +21,7 @@ public protocol NWSAlertsManagerDelegate: class {
}
public class NWSAlertsManager {
public weak var delegate: NWSAlertsManagerDelegate?
public var delegates = MulticastDelegate<NWSAlertsManagerDelegate>()
public typealias Completion = ([NWSAlert]?, NWSError?) -> ()
#if DEBUG
public let updateInterval = TimeInterval(2 * 60) // 2 minutes
......@@ -175,7 +175,9 @@ public class NWSAlertsManager {
self.internalQueue.addOperation {
self.extendedInfoBeingFetched.remove(alert)
}
self.delegate?.extendedInfoAvailable(from: self, for: self.alerts[alertIndex])
self.delegates.invoke { (delegate) in
delegate.extendedInfoAvailable(from: self, for: self.alerts[alertIndex])
}
}
}
}
......@@ -203,7 +205,9 @@ public class NWSAlertsManager {
// A deadlock shouldn't happen unless main thread waits on internalQueue, which it doesn't.
DispatchQueue.main.sync {
self.alerts = resultingAlerts
self.delegate?.alertsListDidChange(in: self)
self.delegates.invoke { (delegate) in
delegate.alertsListDidChange(in: self)
}
}
fetchAllExtendedInfo(for: resultingAlerts)
}
......
//
// NWSAlertViewController.swift
// 1Weather
//
// Created by Demid Merzlyakov on 26.04.2021.
//
import UIKit
class NWSAlertViewController: UIViewController {
private let coordinator: NWSAlertCoordinator
private let viewModel: NWSAlertViewModel
private var localizationObserver: Any?
init(coordinator: NWSAlertCoordinator, viewModel: NWSAlertViewModel) {
self.viewModel = viewModel
self.coordinator = coordinator
super.init(nibName: nil, bundle: nil)
self.viewModel.delegate = self
}
@available(*, unavailable)
required init?(coder: NSCoder) { return nil }
override func viewDidLoad() {
prepareViewController()
prepareNavigationBar()
}
deinit {
if let observer = localizationObserver {
NotificationCenter.default.removeObserver(observer)
}
}
private func close() {
self.navigationController?.dismiss(animated: true, completion: { [weak self] in
guard let self = self else { return }
self.coordinator.viewControllerDidEnd(controller: self)
})
}
@objc private func handleCloseButton() {
close()
}
private func updateUI() {
}
}
//MARK: - UI Setup
extension NWSAlertViewController {
func prepareViewController() {
view.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
let closeButton = UIBarButtonItem(title: "general.close".localized().capitalized,
style: .done,
target: self,
action: #selector(handleCloseButton))
navigationItem.leftBarButtonItem = closeButton
localizationObserver = NotificationCenter.default.addObserver(forName: .localizationChange, object: nil, queue: .main, using: { [weak self] _ in
self?.prepareNavigationBar()
})
}
func prepareNavigationBar() {
title = "notifications.title".localized()
}
}
extension NWSAlertViewController: ViewModelDelegate {
func viewModelDidChange<P: ViewModelProtocol>(model:P) {
DispatchQueue.main.async {
self.updateUI()
}
}
}
......@@ -10,7 +10,7 @@ import UIKit
class NotificationsViewController: UIViewController {
private let coordinator: NotificationsCoordinator
private let viewModel = NotificationsViewModel()
private var localizationObserver:Any?
private var localizationObserver: Any?
private let log = Logger(componentName: "NotificationsViewController")
private let tableView = UITableView()
......@@ -41,7 +41,10 @@ class NotificationsViewController: UIViewController {
}
private func close() {
self.navigationController?.dismiss(animated: true)
self.navigationController?.dismiss(animated: true, completion: { [weak self] in
guard let self = self else { return }
self.coordinator.viewControllerDidEnd(controller: self)
})
}
@objc private func handleCloseButton() {
......@@ -101,12 +104,20 @@ extension NotificationsViewController: UITableViewDelegate, UITableViewDataSourc
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
viewModel.select(index: indexPath.row)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
UITableView.automaticDimension
}
}
extension NotificationsViewController: ViewModelDelegate {
extension NotificationsViewController: NotificationsViewModelDelegate {
func viewModel(_ viewModel: NotificationsViewModel, didSelect alert: NWSAlert) {
coordinator.open(nwsAlert: alert)
}
func viewModelDidChange<P: ViewModelProtocol>(model:P) {
DispatchQueue.main.async {
self.tableView.reloadData()
......
//
// NWSAlertViewModel.swift
// 1Weather
//
// Created by Demid Merzlyakov on 26.04.2021.
//
import Foundation
class NWSAlertViewModel: ViewModelProtocol {
public weak var delegate: ViewModelDelegate?
public private(set) var alert: NWSAlert
private let alertsManager: NWSAlertsManager
deinit {
alertsManager.delegates.remove(delegate: self)
}
public init(alert: NWSAlert, alertsManager: NWSAlertsManager = LocationManager.shared.nwsAlertsManager) {
self.alert = alert
self.alertsManager = alertsManager
alertsManager.delegates.add(delegate: self)
}
}
extension NWSAlertViewModel: NWSAlertsManagerDelegate {
func alertsListDidChange(in alertsManager: NWSAlertsManager) {
// do nothing
}
func extendedInfoAvailable(from alertsManager: NWSAlertsManager, for alert: NWSAlert) {
if self.alert == alert {
self.alert = alert
self.delegate?.viewModelDidChange(model: self)
}
}
}
......@@ -7,19 +7,30 @@
import Foundation
protocol NotificationsViewModelDelegate: ViewModelDelegate {
func viewModel(_ viewModel: NotificationsViewModel, didSelect alert: NWSAlert)
}
class NotificationsViewModel: ViewModelProtocol {
public weak var delegate:ViewModelDelegate?
public weak var delegate: NotificationsViewModelDelegate?
private let alertsManager: NWSAlertsManager
public init(alertsManager: NWSAlertsManager = LocationManager.shared.nwsAlertsManager) {
self.alertsManager = alertsManager
alertsManager.delegate = self
alertsManager.delegates.add(delegate: self)
}
public var alerts: [NWSAlert] {
alertsManager.alerts
}
public func select(index: Int) {
self.delegate?.viewModel(self, didSelect: alerts[index])
}
deinit {
alertsManager.delegates.remove(delegate: self)
}
}
extension NotificationsViewModel: NWSAlertsManagerDelegate {
......
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