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



我第一次在VIPER架构中编写应用程序,不明白UITableView委托和数据源方法应该进入View、Presenter还是Interactior?我在一些链接中发现它应该是View类的一部分,但这似乎不对。即使它是View的一部分,数据将如何到达那里,因为从技术上讲,View不应该向演示者索取数据。演示者应该自己推送数据。

您读取的链接是正确的,具有VIPER架构的应用程序中UITableView的委托和数据源方法应该保留在View中。关于数据将如何到达视图的结论,这是错误的,因为View本身应该要求Presenter带来数据,然后演示者要求Interactor从web或数据库加载数据。如果您对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/

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

如果您不希望视图要求演示者提供数据,那么您可以按照我描述的方式进行操作。数据源类包含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向演示者索要数据并没有错。

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

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和tableviewDataSource与通信协议连接起来,并且可以很好地实现,但这取决于您的团队所采用的方法。VIPER是关于推动大型项目的,它的实践必须方便整个团队参与。

最新更新