VIPER 中 UITableView 委托和数据源的实现

Implementation of UITableView delegate and datasource in VIPER

我是第一次在 VIPER 架构中编写应用程序,无法理解 UITableView 委托和数据源方法是否应该进入 View、Presenter 或 Interactor?我在一些链接中发现它应该是 View class 的一部分,但这似乎并不正确。即使它是 View 的一部分,数据将如何到达那里,因为从技术上讲,View 不应该向演示者请求数据。 Presenter应该自己推送数据。

您阅读的 link 是正确的,在具有 VIPER 架构的应用程序中 UITableView 的委托和数据源方法应该保留在View。 关于你关于数据如何到达视图的结论,这是错误的,因为 View 本身应该要求 Presenter 带来数据,然后 Presenter 要求 Interactor 从网络加载数据或数据库。 如果您对 VIPER 架构有任何疑问,我绝对推荐这些文章:

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

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

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

是的,数据源和委托是视图层的一部分。

如果您不希望您的视图向演示者询问数据,那么您可以按照我的描述进行操作。 数据源 class 包含 viewModels(虚拟对象)。然后,您可以通过接口进行通信。我的意思是你可能会更好地理解一些例子:

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

但在我看来,View 向演示者索要数据并没有错。

允许table将数据源留在视图中(如果我们不考虑任何其他层,这可能是正确的位置)。然而,从 SOLID 的角度来看,它并不是 100% 正确的。 VIPER 是为了推动 单一职责原则 而组成的。在 View 中留下 table datasource/delegate 很可能会因为与视图无关的代码而导致违反这一原则,这在 delegate/datasource 中是可能的。最好将 View 限制为 负责 View 相关任务。理想情况下,它不应该充当数据提供者,甚至不应该充当 table 视图的数据源。也就是说,最佳实践是分别从 Presenter 和 View 中实现 table view DataSource/Delegate 。 在 View 中声明数据源(委托)并将其分配给您的 table:

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

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

然后该数据源将通过输出协议与视图或呈现器(如果需要)通信,这在 VIPER 中很常见。

DataSource 获取数据的方式是从 Presenter,但不是通过它自己,而是通过 View,后者获取数据来自Presenter的输出界面。后者有时是可以讨论的,并且取决于您应用程序的复杂性。可以使用通信协议桥接 Presenter 和 tableview DataSource,并且可以很好地实现,但这取决于您的团队采用的方法。 VIPER 旨在推动大型项目,其实践必须方便整个团队参与。