UI layer tips

There are certain things that your Observables need to satisfy in the UI layer when binding to UIKit controls.

Threading

Observables need to send values on MainScheduler(UIThread). That's just a normal UIKit/Cocoa requirement.

It is usually a good idea for you APIs to return results on MainScheduler. In case you try to bind something to UI from background thread, in Debug build RxCocoa will usually throw an exception to inform you of that.

To fix this you need to add observeOn(MainScheduler.instance).

NSURLSession extensions don't return result on MainScheduler by default.

Errors

You can't bind failure to UIKit controls because that is undefined behavior.

If you don't know if Observable can fail, you can ensure it can't fail using catchErrorJustReturn(valueThatIsReturnedWhenErrorHappens), but after an error happens the underlying sequence will still complete.

If the wanted behavior is for underlying sequence to continue producing elements, some version of retry operator is needed.

Sharing subscription

You usually want to share subscription in the UI layer. You don't want to make separate HTTP calls to bind the same data to multiple UI elements.

Let's say you have something like this:

let searchResults = searchText
    .throttle(0.3, $.mainScheduler)
    .distinctUntilChanged
    .flatMapLatest { query in
        API.getSearchResults(query)
            .retry(3)
            .startWith([]) // clears results on new search term
            .catchErrorJustReturn([])
    }
    .shareReplay(1)              // <- notice the `shareReplay` operator

What you usually want is to share search results once calculated. That is what shareReplay means.

It is usually a good rule of thumb in the UI layer to add shareReplay at the end of transformation chain because you really want to share calculated results. You don't want to fire separate HTTP connections when binding searchResults to multiple UI elements.

Also take a look at Driver unit. It is designed to transparently wrap those shareReply calls, make sure elements are observed on main UI thread and that no error can be bound to UI.

results matching ""

    No results matching ""