MVP架构模式的例子。迅速

问题描述 投票:0回答:2

我想学习经典的MVP架构模式并为此努力落实斯威夫特天气应用程序。我在理论学会了如何工作,但实际上是停留在基本的了解。现在我有一个模型:

模型

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
    }

视图

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)
        }
    }
}

主持人

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
            }
        }
    }
}

Presenter我接收来自网络服务的数据,但我不明白如何使用这些数据更新View(如何实现Presenter协议),因为View不应该知道的模式,但在我的情况下,它会知道(任何想法来实现经典的MVP将不胜感激!

而第二个问题:如何在Presenter实施协议得到Model(因为它是在我从https://www.youtube.com/watch?v=qzTeyxIW_ow拍摄的照片所示)enter image description here

ios swift design-patterns mvp
2个回答
1
投票

更改

func showWeather(data: WeatherModel)

func showWeather(temperature: String, pressure: String, humidity: String)

从视图中演示移动这些字符串的建设。通过这种方式,视图保持无知的模型。

发言人应该不仅对协议直接对话完整视图。


1
投票

你可以试试这个,在MVP的主持人将采取更新视图的照顾,所以修改你的演讲有视图属性。这里的观点主张不过是WeatherController实例。

在MVP而言,UIViewController的子类是事实上的意见,而不是主持人。

    class WeatherPresenter : WeatherViewPresenter {
         unowned let view: WeatherView
         let weather: WeatherModel

         required init(view: WeatherView, weather: WeatherModel) {
            self.view = view
            self.weather = weather
         }

        func updateWeatherView() {
           //...update properties on your weather view
           self.view.setTemperature(self.weather.temperature)
        }
    }

例如,要更新温度的标签,有一个协议设定温度值。你可以有多种方法来设置多个属性或具有一个用于所有天气看你的UI元素。

protocol WeatherView: class {
    func setTemperature(temp: String)
    //same for pressure, humid etc
}

现在写的天气节目主持人的协议

protocol WeatherViewPresenter {
    init(view: WeatherView, weather: WeatherModel)
    func updateWeatherView()
}

现在,你有天气类主持人的设置,你可以使用它像

class WeatherViewController : UIViewController, WeatherView {
    var presenter: WeatherViewPresenter!

    override func viewDidLoad() {
        super.viewDidLoad()
          let model = //your weather model
          presenter = WeatherPresenter(view: self, weather: model)
    }

    func setTemperature(temp: String) {
        self.temperatureLabel.text = temp
    }

}

你从气象数据后,只需拨打self.presenter.updateWeatherView()更新天气视图。

有关详细信息,请refer

© www.soinside.com 2019 - 2024. All rights reserved.