Model–view–presenter is a derivation of the model–view–controller architectural pattern. In MVP, the presenter assumes the functionality of the "middle-man". In MVP, all presentation logic is pushed to the presenter.
The beauty of the MVP is that its easy to learn and to quickly adapt to. The MVP separates the job of the View controller and breaks the MVC to make it easy to manage each part of your code. People call the MVC a "Massive view controller" and that is because the View Controller holder all of our logic. The business logic and the UI logic which leads to a huge file holding every case we have for the UI and what it should do.
To simplify the MVP allows the View to handle all UI logic "the how" and the Presenter tells the View what to show "the what" and the Model stays the same our date model. Below you can find a simple MVP swift implementation. you can use to simplify your needs and your basic delegate functions between the Presenter and the View
/// BaseView is used to setup the delegate with the default functions
protocol BaseView: class {
func setSucceeded()
func startLoading()
func finishLoading()
func setError()
}
extension BaseView {
func setSucceeded() { }
func startLoading() { }
func finishLoading() { }
func setError() { }
}
/// BasePresenter is used to setup the presenter with the default neeeded fucntions
protocol BasePresenter {
associatedtype View
var view: View? { get set }
var isAttached: Bool { get }
func attachView(_ view: View)
func detachView(_ view: View)
}
/// Default implementation for the `isAttached()` method just checks if the `view` is non nil.
extension BasePresenter {
var isAttached: Bool { return view != nil }
}
class BaseMvpController<V, P: BasePresenter>: UIViewController {
typealias View = V
private(set) var presenter: P!
// MARK: - Initializers
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
presenter = createPresenter()
}
override public init(nibName: String?, bundle: Bundle?) {
super.init(nibName: nibName, bundle: bundle)
presenter = createPresenter()
}
/// Override and return a presenter in a subclass.
func createPresenter() -> P {
preconditionFailure("MVP method `createPresenter()` must be override in a subclass and do not call `super.createPresenter()`!")
}
deinit {
guard let view = self as? P.View else {return}
if let presenter = presenter {
presenter.detachView(view)
}
}
// MARK: - Lifecycle
override func viewWillAppear(_ animated: Bool) {
guard let view = self as? P.View else {
preconditionFailure("MVP ViewController must implement the view protocol `\(View.self)`!")
}
//theme
super.viewWillAppear(animated)
if !presenter.isAttached {
presenter.attachView(view)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
}
}
Add new comment