'What is the equivalent of RACChannel in RxSwift?

I want to make one-way binding from UIViewController to VewModel, in ReactiveObjC I've used RACChannel. What is the equivalent of a later one or what is the best way to do that?



Solution 1:[1]

I'm going to have to answer the more general question here. That of binding the view controller to the view model.

Here's a good video for Reactive View Models

A well constructed reactive view model is a single function that takes a number of Observable inputs from the view inputs and returns a number of Observables that are bound to the views meant for output.

A simple example login view model...

func login(
    callServer: @escaping (URLRequest) -> Observable<Data>,
    email: Observable<String>,
    password: Observable<String>,
    login: Observable<Void>
) -> (
    loggedIn: Observable<Void>,
    errorMessage: Observable<String>
) {
    let loginResponse = login
        .withLatestFrom(
            Observable.combineLatest(email, password) { makeLoginURLRequest(email: $0, password: $1) }
        )
        .flatMapLatest {
            callServer($0)
                .map { try JSONDecoder().decode(LoginResponse.self, from: $0) }
                .materialize()
        }
    
    let loggedIn = loginResponse
        .compactMap { $0.element != nil ? () : .none }
    
    let errorMessage = loginResponse
        .compactMap { $0.error?.localizedDescription }
    
    return (
        loggedIn: loggedIn,
        errorMessage: errorMessage
    )
}

Call it in the view controller's viewDidLoad like this:

let (loggedIn, errorMessage) = login(
    callServer: URLSession.shared.rx.data(request:),
    email: emailTextField.rx.text.orEmpty.asObservable(),
    password: passwordTextField.rx.text.orEmpty.asObservable(),
    login: loginButton.rx.tap.asObservable()
)

loggedIn
    .bind(onNext: { print("user is now logged in!") })
    .disposed(by: disposeBag)

errorMessage
    .bind(onNext: { print("display error message", $0) })
    .disposed(by: disposeBag)

Lastly, if you don't like using tuples, you can replace them with structs.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1