Поиск элементов в связанном RxDataSource с itens, обернутым в модели секций
Я пытаюсь отфильтровать свои контакты, но они обернуты в ContactSections, и мне трудно это сделать. Вот элемент источника данных, который связан с UITableView с помощью RxCocoa:
import RxDataSources
struct ContactSection {
var header: String
var items: [Contact]
}
extension ContactSection: SectionModelType {
init(original: ContactSection, items: [Contact]) {
self = original
self.items = items
}
}
В основном он содержит заголовок, который является начальным из контактов, содержащихся в элементах (например: "A" для "Анна", "Аманда"...)
Вот как это связано:
let dataSource = RxTableViewSectionedReloadDataSource<ContactSection>(
configureCell: { dataSource, tableView, indexPath, contact in
let cell = tableView.dequeueReusableCell(forIndexPath: indexPath, ofType: ContactListCell.self)
cell.setup(with: contact)
return cell
})
dataSource.titleForHeaderInSection = { dataSource, index in
return dataSource.sectionModels[index].header
}
viewModel.filteredItems
.asObservable()
.map { $0! }
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: bag)
searchBar.rx
.text
.orEmpty
.distinctUntilChanged()
.bind(to: viewModel.searchValue)
.disposed(by: bag)
И наконец, вот так выглядит ViewModel (я использую MVVM + RxCocoa)
import RxCocoa
import RxSwift
final class ContactListViewModel {
// MARK: Properties
var items = BehaviorRelay<[ContactSection]?>(value: [])
var searchValue: Variable<String> = Variable("")
var filteredItems: Variable<[ContactSection]?> = Variable([])
private let dataPresenter = ContactsDataPresenter()
private let bag = DisposeBag()
lazy var itemsObservable: Observable<[ContactSection]?> = self.items.asObservable()
lazy var searchValueObservable: Observable<String> = self.searchValue.asObservable()
lazy var filteredItemsObservable: Observable<[ContactSection]?> = self.filteredItems.asObservable()
init() {
searchValueObservable.subscribe(onNext: { value in
self.itemsObservable.map({ $0?.filter({
if value.isEmpty { return true }
// I NEED TO FILTER THESE CONTACTS HERE BUT INTO THEIR OWN SECTIONS.
})
}).bind(to: self.filteredItems)
.disposed(by: self.bag)
}).disposed(by: bag)
}
}
// MARK: - Public
extension ContactListViewModel {
func getContacts() {
_ = dataPresenter.getContacts()
.asDriver(onErrorJustReturn: items.value!)
.drive(items)
.disposed(by: bag)
}
}