From 52d02ea3a1fff9758e6c9685335c913e50ccf689 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 21 Jan 2025 13:59:17 -0600 Subject: [PATCH] now using diffable datasource Signed-off-by: Matt Bruce # Conflicts: # EmployeeDirectory/ViewControllers/EmployeesViewController.swift Signed-off-by: Matt Bruce --- EmployeeDirectory/Models/Employee.swift | 2 +- .../EmployeesViewController.swift | 48 ++++++++++--------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/EmployeeDirectory/Models/Employee.swift b/EmployeeDirectory/Models/Employee.swift index 08e4b82..c55b68e 100644 --- a/EmployeeDirectory/Models/Employee.swift +++ b/EmployeeDirectory/Models/Employee.swift @@ -27,7 +27,7 @@ public enum EmployeeType: String, Codable, CustomStringConvertible { /// Employee Object /// JSON Object defintion /// - https://square.github.io/microsite/mobile-interview-project/ -public struct Employee: Codable { +public struct Employee: Hashable, Codable { /// The unique identifier for the employee. Represented as a UUID. public let uuid: UUID diff --git a/EmployeeDirectory/ViewControllers/EmployeesViewController.swift b/EmployeeDirectory/ViewControllers/EmployeesViewController.swift index cfb192e..b732bcb 100644 --- a/EmployeeDirectory/ViewControllers/EmployeesViewController.swift +++ b/EmployeeDirectory/ViewControllers/EmployeesViewController.swift @@ -31,24 +31,46 @@ class EmployeesViewController: UIViewController { /// Will show specific state of the viewModel private var footerView: TableFooterView? + private var dataSource: UITableViewDiffableDataSource! + // MARK: - Public Methods public override func viewDidLoad() { super.viewDidLoad() setupUI() + setupDataSource() bindViewModel() viewModel.fetchEmployees() } // MARK: - Private Methods - + + + /// Setup TableView dataSource + private func setupDataSource() { + dataSource = UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, employee in + guard let cell = tableView.dequeueReusableCell(withIdentifier: EmployeeTableViewCell.identifier,for: indexPath) as? EmployeeTableViewCell else { + return UITableViewCell() + } + cell.configure(with: EmployeeCellViewModel(employee: employee)) + return cell + } + } + + /// Snapshot Handling + private func applySnapshot(employees: [Employee]) { + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([0]) + snapshot.appendItems(employees, toSection: 0) + dataSource.apply(snapshot, animatingDifferences: true) + } + /// Setup the UI by adding the views to the main view private func setupUI() { view.backgroundColor = .white // Configure TableView tableView.register(EmployeeTableViewCell.self, forCellReuseIdentifier: EmployeeTableViewCell.identifier) - tableView.dataSource = self view.addSubview(tableView) tableView.frame = view.bounds @@ -70,10 +92,8 @@ class EmployeesViewController: UIViewController { private func bindViewModel() { viewModel.$employees .receive(on: RunLoop.main) - .sink { [weak self] _ in - self?.updateFooter() - self?.tableView.reloadData() - self?.tableView.refreshControl?.endRefreshing() + .sink { [weak self] employees in + self?.applySnapshot(employees: employees) } .store(in: &cancellables) @@ -139,19 +159,3 @@ extension EmployeesViewController { viewModel.changeMode(to: selectedMode) } } - -/// Mark: - UITableViewDataSource -extension EmployeesViewController: UITableViewDataSource { - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return viewModel.employees.count - } - - public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - guard let cell = tableView.dequeueReusableCell(withIdentifier: EmployeeTableViewCell.identifier, for: indexPath) as? EmployeeTableViewCell else { - return UITableViewCell() - } - let employee = viewModel.employees[indexPath.row] - cell.configure(with: EmployeeCellViewModel(employee: employee)) - return cell - } -}