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 旨在推动大型项目,其实践必须方便整个团队参与。
我是第一次在 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 旨在推动大型项目,其实践必须方便整个团队参与。