Aleksei Danilov
Aleksei Danilov

Reputation: 645

How send parameter to view model with RxSwift in MVVM architecture?

I have service method for login to facebook that have one parameter of type View Controller. I user RxSwift and MVVM. In View Controller I bind button tap to view model's observer and subscribe to it for invoke service inside. How I can send parameter view controller to view model for sending to my service?

Here is the problem exactly

self.authService.signInWithFacebook(from: ???)

class AuthService: AuthServiceType {
 // ...

  func signInWithFacebook(from: UIViewController?) -> Observable<Result<Void, FirebaseLoginError>> {
     // ...
    }

 // ...
}


class LoginViewModel {

    let facebookLoginDidTapObserver: AnyObserver<Void>

    let facebookLoginDidTapObservable: Observable<Void>

    private let authService: AuthServiceType

    init(authService: AuthServiceType = AuthService()) {

        self.authService = authService

        let facebookLoginDidTap = PublishSubject<Void>()
        facebookLoginDidTapObserver = facebookLoginDidTap.asObserver()
        facebookLoginDidTapObservable = facebookLoginDidTap.asObservable()

        facebookLoginDidTapObservable
            .throttle(0.5, scheduler: MainScheduler.instance)
            .subscribe(onNext: { tap in

                return self.authService.signInWithFacebook(from: ???)
            })
            .disposed(by: disposeBag)
    }

}


class LoginViewController: UIViewController {

    facebookLoginButton.rx
        .tap
        .bind(to: viewModel.facebookLoginDidTapObserver)
        .disposed(by: disposeBag) 


} 

Upvotes: 0

Views: 2127

Answers (1)

Val&#233;rian
Val&#233;rian

Reputation: 1118

You can pass the VC itself to the VM and then expose the result of the authService. It is best not to subscribe in your VM so I changed that as well.

class LoginViewModel {
  let facebookLoginDidTapObserver: AnyObserver<UIViewController>

  let facebookLoginDidTapObservable: Observable<Result<Void, FirebaseLoginError>>

  private let authService: AuthServiceType

  init(authService: AuthServiceType = AuthService()) {

    self.authService = authService

    let facebookLoginDidTap = PublishSubject<UIViewController>()
    self.facebookLoginDidTapObserver = facebookLoginDidTap.asObserver()

    self.facebookLoginDidTapObservable = facebookLoginDidTap.asObservable()
        .throttle(0.5, scheduler: MainScheduler.instance)
        .flatMapLatest(onNext: { vc in
            return self.authService.signInWithFacebook(from: vc)
        })
  }
}

class LoginViewController: UIViewController {

facebookLoginButton.rx
    .tap
    .map { [unowned self] _ in self }
    .bind(to: viewModel.facebookLoginDidTapObserver)
    .disposed(by: disposeBag) 

}

Upvotes: 1

Related Questions