Rob Emmanuel
Rob Emmanuel

Reputation: 33

RxSwift - Why wrap ControlProperty trait into a Driver?

In the official RxSwift documentation, it's described that traits Driver and ControlProperty share many similarities between them (can't error out, observe occurs on main scheduler, share and replay side effects), but at the same time in the example provided ControlProperty rx.text is being wrapped into a Driver.

So the questions would be:

Here I attach the referenced code from the documentation:

From:

let results = query.rx.text
    .throttle(0.3, scheduler: MainScheduler.instance)
    .flatMapLatest { query in
        fetchAutoCompleteItems(query)
            .observeOn(MainScheduler.instance)  // results are returned on MainScheduler
            .catchErrorJustReturn([])           // in the worst case, errors are handled
    }
    .share(replay: 1)                           // HTTP requests are shared and results replayed
                                                // to all UI elements

results
    .map { "\($0.count)" }
    .bind(to: resultCount.rx.text)
    .disposed(by: disposeBag)

results
    .bind(to: resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in
        cell.textLabel?.text = "\(result)"
    }
    .disposed(by: disposeBag)

To:

let results = query.rx.text.asDriver()        // This converts a normal sequence into a `Driver` sequence.
    .throttle(0.3, scheduler: MainScheduler.instance)
    .flatMapLatest { query in
        fetchAutoCompleteItems(query)
            .asDriver(onErrorJustReturn: [])  // Builder just needs info about what to return in case of error.
    }

results
    .map { "\($0.count)" }
    .drive(resultCount.rx.text)               // If there is a `drive` method available instead of `bind(to:)`,
    .disposed(by: disposeBag)              // that means that the compiler has proven that all properties
                                              // are satisfied.
results
    .drive(resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in
        cell.textLabel?.text = "\(result)"
    }
    .disposed(by: disposeBag)

Thanks and best regards!

Upvotes: 3

Views: 1376

Answers (1)

Daniel T.
Daniel T.

Reputation: 33967

In the first example, the throttle that is used returns an Observable.

In the second example, because of the asDriver() call, a different throttle is used that returns a Driver (i.e., a SharedSequence<DriverSharingStrategy, String>)

Your confusion likely stems from the fact that there are two throttle functions in the RxSwift library. One is an extension on ObservableType (ControlProperty is an extension of ObservableType) whereas the other is an extension on SharedSequenceConvertibleType (Driver is an extension of that.)

Upvotes: 1

Related Questions