简体   繁体   中英

Implementation of UITableView delegate and datasource in VIPER

I'm writing an app in VIPER architecture for the first time, and can't understand if the UITableView delegate and datasource methods should go into the View, Presenter or the Interactor? I found in some links that it should be part of View class, but that doesn't seem to be right. And even if it's part of View, how will the data reach there because View should technically not ask for data from the presenter. Presenter should push data itself.

The link's you read were correct, the delegate and datasource methods for an UITableView in an app with VIPER architecture should stay in the View . About your conclusion about how the data will reach the view, it's wrong because the View itself should ask for Presenter bring the data, and then the Presenter ask for Interactor load the data from web or a database. If you have any questions about the VIPER architecture I definitely recommend these articles:

Article 1: https://blog.mindorks.com/building-ios-app-with-viper-architecture-8109acc72227

Article 2: https://cheesecakelabs.com/blog/best-practices-viper-architecture/

Article 3: https://cheesecakelabs.com/blog/ios-project-architecture-using-viper/

Yes, data source and delegate are the parts of a view layer.

If you do not want your view to ask presenter for data, then you can do it like I describe it. The data source class holds viewModels(dummy objects). You can then communicate via an interface. I mean you might understand better on some example:

protocol SomeViewProtocol {
    func set(withVMS vms: [SomeViewModel])
}

final class SomeVC: SomeViewProtocol {

    let dataSource: SomeDataSource
    let tableView: UITableView

    override func viewDidLoad() {
        tableView.dataSource = dataSource
    }

    func set(withVMS vms: [SomeViewModel]) {
        someDataSource.set(withVMS: vms)
        tableView.reloadData()
    }
}
protocol SomePresenterProtocol {
    ...
}

final class SomePresenter: SomePresenterProtocol {

    fileprivate let view: SomeViewProtocol

    //After view did load
    func initAfterLoad() {
        .
        .
        .

        view.set(withVMS: viewModels)
    }
}

But from my perspective, there is nothing wrong with View asking the presenter for the data.

It is permittable to leave datasource in View (and is probably the right place, if we don't consider any other layers). However, it is not 100% correct from SOLID perspective. VIPER was made up to push single responsibilty principle . Leaving table datasource/delegate in View may well lead to breaking this principle due to non-view-related code, potentially possible in delegate/datasource. It is much better to restrict View to be only responsible for View -related tasks. It should not, ideally, serve as data provider, even as a datasource for a tableview. That said, the best practice is to implement table view DataSource/Delegate separately from either Presenter and the View. Declare datasource(delegate) within View and assign it to your table:

let dataSource: DataSource! // Implements both TableView DataSource and Delegate protocols
let tableView: UITableView!

override func viewDidLoad() {
    tableView.dataSource = dataSource
    tableView.delegate = dataSource
}

That datasource will then communicate with either the view or presenter (if needed) via output protocols, as it is common in VIPER.

The way DataSource would get its data is from Presenter , but not by itself, but rather via View , which obtains it data from Presenter 's output interface. The latter is sometimes discussable and depends on complexity of your app. It is possible to bridge Presenter and tableview DataSource with communication protocols and can be implemented well, but that depends on the approach adopted in your team. VIPER is about driving big projects and its practices must be convenient for entire team involved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM