【RxSwift practice Series 2/3】 Thinking in RX-Create and Drive functions, we want to implement the cell button function in uITableView. Similarly, we subscribe to the button directly on the cell, and when a click request is received, UserDefaults goes up

As follows:

searchFiled.rx.text
            .filter{($0? .lengthOfBytes(using: .utf8))! >0 // The length is greater than 1
            }
            .throttle(0.5, scheduler: MainScheduler.instance) // Delay execution for 0.5 seconds
            .flatMap{
                ListViewModel().searchFromApi(repositoryName:String(describing: $0!). ) } .asDriver(onErrorJustReturn: []) .drive(resultTableView.rx.items(cellIdentifier:"SearchTableViewCell", cellType: SearchTableViewCell.self)) {
                (tableView, element, cell) in
                cell.nameLabel.text = element.name
                cell.codeLabel.text = element.code
                cell.addBtn.rx.tap.subscribe(
                    onNext: {
                        var stocks = UserDefaults.standard.array(forKey: "stockSelected")  as! [String]
                        stocks.append(element.code)
                        UserDefaults.standard.set(stocks, forKey: "stockSelected")
                        cell.addBtn.setTitle("Concerned".for: .normal)
                    }
                    ).disposed(by: rx.disposeBag) 
            }
            .disposed(by: rx.disposeBag)
Copy the code

However, the problem was found in the actual operation. When the input of the search box was constantly changing, the cell was also constantly refreshing. When the cell was reused, the button would be subscribed for many times, causing serious bugs. So we’re going to use a method called prepareForReuse

    private(set) var disposeBag = DisposeBag(a)/ / SearchTableViewCell in implementation
    override func prepareForReuse(a) {
        super.prepareForReuse()
        disposeBag = DisposeBag()}Copy the code

Each time a cell is reused, the previous disposeBag is released, and a new disposeBag object is created for the cell, avoiding multiple subscriptions.

cell.addBtn.rx.tap.subscribe(
        onNext: {
            var stocks = UserDefaults.standard.array(forKey: "stockSelected")  as! [String]
            stocks.append(element.code)
            UserDefaults.standard.set(stocks, forKey: "stockSelected")
            cell.addBtn.setTitle("Concerned".forDisposed (by: cell. DisposeBag)// Note that here is the disposeBag of cellCopy the code

This allows us to implement the button on the cell.

The display of the home page list is the same as that of the search list. There is no further discussion here. The difficulty here is that the stock price is updated without refreshing the TableView.

ListViewModel().getFromApi(repositoryName: "").subscribe(
    onNext:{ rs in Observable"[ListModel]>
        .just(rs)
        .bind(to: self.resultTableView.rx.items(cellIdentifier: "ListTableViewCell", cellType: ListTableViewCell.self)) {(_, model:ListModel, cell:ListTableViewCell) in
            
            // The scheduled task is executed every two seconds
            Observable<Int>.interval(2, scheduler: MainScheduler.instance).subscribe { (event) in
                ListViewModel().getOne(repositoryName: model.symbol)
                .subscribe(
                    onNext:{ rs in Observable<ListModel>
                        .just(rs)
                        .subscribe{
                            cell.currentLabel.text = String(describing: rs.current)
                            cell.nameLabel.text = rs.name
                            cell.codeLabel.text = rs.code
                        }.disposed(by: self.rx.disposeBag)
                    }
                ).disposed(by: self.rx.disposeBag)
            }.disposed(by: self.rx.disposeBag)
        }.disposed(by: self.rx.disposeBag)
    }
).disposed(by: rx.disposeBag)

Copy the code

In the bound cell, a scheduled task interval is executed for the entire cell to obtain network data once every second and subscribe to the data to update cell elements, thus realizing the update without refreshing of the cell. It only took 3 lines of code to do this!

The rxSwift application to add the stock symbol to the real-time refresh price is complete here, and the example code can be found here.

There are still many defects and need to be optimized in the code: for example, many if and else can be done more succinctly with rxSwift, many errors and exceptions are not dealt with, the prompt of network authorization, and the home page is not updated in time after adding the stock symbol. You can try to optimize your code with rxSwift.

Link to issue 3:

【RxSwift Practice Series 1/3】 Why use RxSwift

【RxSwift Practice Series 2/3】 Thinking in RX-Create and Drive

【RxSwift practice Series 3/3】 Thinking in RX-UitableView