【问题标题】:Implementation of UITableView delegate and datasource in VIPERVIPER中UITableView委托和数据源的实现
【发布时间】:2017-10-23 10:43:25
【问题描述】:

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

【问题讨论】:

    标签: ios swift uitableview viper-architecture


    【解决方案1】:

    您阅读的链接是正确的,具有 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/

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

        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 致力于推动大型项目,其实践必须方便整个团队参与。

        【讨论】:

          猜你喜欢
          • 2012-07-01
          • 2016-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-04
          • 1970-01-01
          • 2015-11-05
          相关资源
          最近更新 更多