Реализация делегата UITableView и источника данных в VIPER

Я пишу приложение в архитектуре VIPER впервые и не могу понять, UITableView Методы делегата и источника данных должны входить в View, Presenter или Interactor? В некоторых ссылках я обнаружил, что он должен быть частью класса View, но это не так. И даже если это часть View, как туда будут поступать данные, потому что View технически не должен запрашивать данные у докладчика. Ведущий должен выдвигать данные сам.

3 ответа

Решение

Да, источник данных и делегат являются частями слоя представления.

Если вы не хотите, чтобы ваше мнение запрашивало данные у докладчика, вы можете сделать это так, как я описал. Класс источника данных содержит 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 запрашивает данные у докладчика.

Ссылка, которую вы прочитали, была правильной, методы делегата и источника данных для UITableView в приложении с архитектурой VIPER должен оставаться в View, Что касается вашего заключения о том, как данные достигнут представления, это неправильно, потому что View сам должен просить 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/

Разрешено оставлять источник данных в представлении (и, вероятно, это правильное место, если мы не рассматриваем другие слои). Тем не менее, это не на 100% правильно с точки зрения ТВЕРДОЙ. VIPER был создан, чтобы продвигать принцип единой ответственности. Выход из таблицы источника данных / делегата в View вполне может привести к нарушению этого принципа из-за не связанного с представлением кода, потенциально возможного в делегате / источнике данных. Гораздо лучше ограничить View, чтобы он отвечал только за связанные с View задачи. В идеале он не должен служить поставщиком данных, даже источником данных для просмотра таблицы. Тем не менее, передовой практикой является реализация табличного представления DataSource/Delegate отдельно от Presenter и View. Объявите источник данных (делегат) в 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 и DataSource в виде таблицы с протоколами связи, и их можно хорошо реализовать, но это зависит от подхода, принятого в вашей команде. VIPER - это управление крупными проектами, и его практика должна быть удобной для всей команды.

Другие вопросы по тегам