I want to learn classic MVP architecture pattern and for this try to implement Weather app on Swift. I learned in theory how it should work but practically stuck on basic understanding. For now I have a model:
Model
class WeatherModel: Codable {
var name: String?
var main: Main?
}
class Main: Codable {
var temperature: Float?
var pressure: Int?
var humidity: Int?
private enum CodingKeys: String, CodingKey {
case temperature = "temp"
case pressure
case humidity
}
View
final class WeatherViewController: UIViewController {
@IBOutlet weak var cityTextField: UITextField!
@IBOutlet weak var temperatureLabel: UILabel!
@IBOutlet weak var pressureLabel: UILabel!
@IBOutlet weak var humidityLabel: UILabel!
private var presenter: WeatherPresenter!
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
presenter = WeatherPresenter()
cityTextField.delegate = self
presenter.delegate = self
}
@IBAction func buttonClicked(_ sender: Any) {
let city = cityTextField.text
if let city = city {
presenter.loadWeatherFor(city: city)
}
}
}
extension WeatherViewController: WeatherPresenterProtocol {
// MARK: - WeatherPresenterProtocol
func showWeather(data: WeatherModel) {
if let temperature = data.main?.temperature {
self.temperatureLabel.text = String(temperature)
}
if let pressure = data.main?.pressure {
self.pressureLabel.text = Constants.pressure + String(pressure)
}
if let humidity = data.main?.humidity {
self.humidityLabel.text = Constants.humidity + String(humidity)
}
}
}
Presenter
protocol WeatherPresenterProtocol: class {
func showWeather(data: WeatherModel) // ?
}
final class WeatherPresenter {
var model: WeatherModel!
weak var delegate: WeatherPresenterProtocol?
func loadWeatherFor(city: String) {
Network.shared.getWeather(city) { [weak self] (weather, error) in
DispatchQueue.main.async {
self?.model = weather
}
}
}
}
In Presenter
I receive data from a Network Service but I can't understand how to update View
with this data (how to implement protocol in Presenter
) because View
shouldn't know about model but in my case it will know( Any idea to implement classic MVP will be appreciated!
And second question: how to implement protocol in Presenter
to get Model
(as it is shown in the picture I've taken from https://www.youtube.com/watch?v=qzTeyxIW_ow)
Change
func showWeather(data: WeatherModel)
to
func showWeather(temperature: String, pressure: String, humidity: String)
Move the construction of these strings from the View to the Presenter. This way, the View remains ignorant of the model.
The Presenter should not speak directly to the full View, only to the protocol.