Skip to main content
mvp

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

}

 

Tags

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
2 + 2 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.