Replacing UITableViewDiffableDataSource with DifferenceKit

This commit is contained in:
Selim Mustafaev 2020-12-29 15:10:10 +03:00
parent 7d838e4e07
commit 1c86331d7d
2 changed files with 37 additions and 44 deletions

View File

@ -184,15 +184,7 @@ class Vehicle: Object, Decodable, Identifiable, Differentiable, Cloneable {
var osagoContracts = List<Osago>()
var ads = List<VehicleAd>()
var identifier: String = ""
var id: String {
if self.identifier.isEmpty {
self.identifier = self.number
}
return self.identifier
}
var differenceIdentifier: String { id }
var differenceIdentifier: String { self.number }
func isContentEqual(to source: Vehicle) -> Bool {
return self == source
@ -266,27 +258,19 @@ class Vehicle: Object, Decodable, Identifiable, Differentiable, Cloneable {
if let ads = try container.decodeIfPresent([VehicleAd].self, forKey: .ads) {
self.ads.append(objectsIn: ads)
}
self.identifier = self.number
}
required init() {
super.init()
self.identifier = self.number
}
init(_ number: String) {
self.identifier = number
self.number = number
self.addedDate = Date().timeIntervalSince1970
self.updatedDate = self.addedDate
}
func getNumber() -> String {
if self.identifier.isEmpty {
self.identifier = self.number
}
return self.number
}

View File

@ -5,39 +5,25 @@ import ExceptionCatcher
typealias FilterPredicate<T> = (T) -> Bool
class RealmDiffableDataSourse<Item>: UITableViewDiffableDataSource<DateSection<Item>, Item> where Item: Hashable & ContentEquatable & ContentIdentifiable {
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return snapshot().sectionIdentifiers[section].header
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
}
class RealmSectionedDataSource<Item,Cell> where Item: Object & Identifiable & Dated & Differentiable & Cloneable, Cell: UITableViewCell & ConfigurableCell, Cell.Item == Item {
class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource
where Item: Object & Identifiable & Dated & Differentiable & Cloneable,
Cell: UITableViewCell & ConfigurableCell,
Cell.Item == Item {
private var tv: UITableView
private var data: Results<Item>
private var notificationToken: NotificationToken?
private var sections: [DateSection<Item>] = []
private var cellIdentifier: String
private var lastUpdateTime = Date()
private var dataSource: RealmDiffableDataSourse<Item>!
private var filterPredicate: FilterPredicate<Item>?
init(table: UITableView, data: Results<Item>, cellIdentifier: String = String(describing: Cell.self)) {
self.tv = table
self.data = data
self.cellIdentifier = cellIdentifier
self.dataSource = RealmDiffableDataSourse<Item>(tableView: table) { tv, ip, model -> UITableViewCell? in
let cell = tv.dequeueReusableCell(withIdentifier: self.cellIdentifier, for: ip) as? Cell
cell?.configure(with: model)
return cell
}
self.dataSource.defaultRowAnimation = .fade
self.tv.dataSource = self.dataSource
super.init()
self.tv.dataSource = self
self.tv.reloadData()
self.notificationToken = self.data.observe { changes in
switch changes {
@ -51,6 +37,30 @@ class RealmSectionedDataSource<Item,Cell> where Item: Object & Identifiable & Da
}
}
// MARK: - UITableViewDataSource
func numberOfSections(in tableView: UITableView) -> Int {
return self.sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.sections[section].elements.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: self.cellIdentifier, for: indexPath) as? Cell else {
return UITableViewCell()
}
let item = self.sections[indexPath.section].elements[indexPath.row]
cell.configure(with: item)
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sections[section].header
}
// MARK: - Public
func item(at indexPath: IndexPath) -> Item {
@ -62,13 +72,12 @@ class RealmSectionedDataSource<Item,Cell> where Item: Object & Identifiable & Da
if let predicate = self.filterPredicate {
items = items.filter(predicate)
}
self.sections = items.groupedByDate()
var snapshot = NSDiffableDataSourceSnapshot<DateSection<Item>, Item>()
snapshot.appendSections(self.sections)
for section in self.sections {
snapshot.appendItems(section.elements, toSection: section)
let newSections = items.groupedByDate()
let changeset = StagedChangeset(source: self.sections, target: newSections)
self.tv.reload(using: changeset, with: animated ? .fade : .none) { newSects in
self.sections = newSects
}
self.dataSource.apply(snapshot, animatingDifferences: animated, completion: nil)
}
func setFilterPredicate(_ predicate: FilterPredicate<Item>?) {