RxRealmDataSources удаление ячейки


#1

ктонибудь работал с данной библиотекой “RxRealmDataSources”.
хотел упростить жизнь, но не тут то было.

запускаю симулятор, первое удаление отлично, второе итд не происходит. Вот код:

@IBOutlet weak var tableView: UITableView!

private let bag = DisposeBag()
private let viewModel = DownloadViewModel()

override func viewDidLoad() {
    super.viewDidLoad()
    
    tableView.register(withClassFromNib: NewTableViewCell.self)
    cellSetup()
}

fileprivate func cellSetup() {
    
    // RxRealm to get Observable<Results>
    let realm = try! Realm(configuration: viewModel.config)
    
    // create data source
    let dataSource = RxTableViewRealmDataSource<PlayerModel>(cellIdentifier: "NewTableViewCell", cellType: NewTableViewCell.self) { cell, index, model in
        cell.titleLabel.text = model.title
        cell.artistLabel.text = model.artist?.name
        cell.themeLabel.text = model.genres.first?.name
        cell.itemBgView.isHidden = true
    }
    
    let changeset = Observable.changeset(from: realm.objects(PlayerModel.self))
        .share()
    
    // bind to table view
    changeset
        .bind(to: tableView.rx.realmChanges(dataSource))
        .disposed(by: bag)

    // react on cell taps
    tableView.rx.realmModelSelected(PlayerModel.self)
        .subscribe { [weak self] id in
            self?.showDetails(id)
        }
        .disposed(by: bag)
    
    // delete row
    tableView.rx.itemDeleted
        .subscribe { [weak self] event in
            guard let element = event.element else { return }
            let model = dataSource.model(at: element)
            self?.viewModel.deleteRow(at: element, model)
        }
        .disposed(by: bag)
}

#2

Удалите share().



#3

к сожалению не помогло…


#4

У вас непонятно что происходит во ViewModel. Пример с таблицей на гитхабе, для удаления ячеек можно исправить так, может поможет:

class ViewController: UIViewController {

    @IBOutlet private var tableView: UITableView!

    private let bag = DisposeBag()
    private lazy var config = Realm.Configuration.defaultConfiguration
    private lazy var realm = try! Realm(configuration: self.config)
    
    override func viewDidLoad() {
        super.viewDidLoad()

        insertRow()
        insertRow()
        insertRow()
        
        let dataSource = RxTableViewRealmDataSource<Lap>(cellIdentifier: "Cell", cellType: PersonCell.self) {cell, ip, lap in
            cell.customLabel.text = "\(ip.row). \(lap.text)"
        }
        
        let laps = Observable.changeset(from: realm.objects(Timer.self).first!.laps)
        
        laps.bind(to: tableView.rx.realmChanges(dataSource)).disposed(by: bag)

        tableView.rx.realmModelSelected(Lap.self).map({ $0.text }).bind(to: rx.title).disposed(by: bag)
        tableView.rx.itemDeleted.withLatestFrom(laps) { $1.0.elements[$0.row] }.bind { [weak self] in self?.deleteRow($0) }.disposed(by: bag)
    }
    
    func insertRow() {
        try! realm.write {
            var timerLaps = realm.objects(Timer.self).first
            if timerLaps == nil {
                realm.add(Timer())
            }
            timerLaps = realm.objects(Timer.self).first!
            timerLaps!.laps.append(Lap())
        }
    }
    
    func deleteRow(_ lap: Lap) {
        try! realm.write {
            let timerLaps = realm.objects(Timer.self).first!.laps
            if let index = timerLaps.index(of: lap) {
                timerLaps.remove(at: index)
            }
        }
    }
}

И если вы делаете что то типа MVVM, Realm не должно быть во ViewController.

P.S. Хотя этот код похоже тоже не работает как надо(((


#5

Кривой этот ваш RxRealmDataSources и конфликтует с RxCocoa, можно как то так закостылить:

private class RxTableDelegate: NSObject, UITableViewDelegate {
    let deleteRow = PublishSubject<Int>()
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        return [
            UITableViewRowAction(style: .destructive, title: "Delete") { [weak self] _, indexPath in
                self?.deleteRow.onNext(indexPath.row)
            }
        ]
    }
}

class ViewController: UIViewController {

    @IBOutlet private var tableView: UITableView!

    private let bag = DisposeBag()
    private lazy var config = Realm.Configuration.defaultConfiguration
    private lazy var realm = try! Realm(configuration: self.config)
    private lazy var tableDelegate = RxTableDelegate()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        insertRow()
        insertRow()
        insertRow()
        
        let dataSource = RxTableViewRealmDataSource<Lap>(cellIdentifier: "Cell", cellType: PersonCell.self) {cell, ip, lap in
            cell.customLabel.text = "\(ip.row). \(lap.text)"
        }
        
        let laps = Observable.changeset(from: realm.objects(Timer.self).first!.laps)
        
        laps.bind(to: tableView.rx.realmChanges(dataSource)).disposed(by: bag)
        
        tableView.rx.realmModelSelected(Lap.self).map({ $0.text }).bind(to: rx.title).disposed(by: bag)
        
        tableView.rx.setDelegate(tableDelegate).disposed(by: bag)
        tableDelegate.deleteRow.withLatestFrom(laps) { $1.0.elements[$0] }.bind { [weak self] in self?.deleteRow($0) }.disposed(by: bag)
    }
    
    func insertRow() {
        try! realm.write {
            var timerLaps = realm.objects(Timer.self).first
            if timerLaps == nil {
                realm.add(Timer())
            }
            timerLaps = realm.objects(Timer.self).first!
            timerLaps!.laps.append(Lap())
        }
    }
    
    func deleteRow(_ lap: Lap) {
        try! realm.write {
            let timerLaps = realm.objects(Timer.self).first!.laps
            if let index = timerLaps.index(of: lap) {
                timerLaps.remove(at: index)
            }
        }
    }
}


#6

Что кривой, к сожалению это так и есть. “Костыль” помог, теперь срабатывает каждый раз! Ещё раз спасибо, уже не в первый раз выручаешь!!!