sergdort / CleanArchitectureRxSwift

Example of Clean Architecture of iOS app using RxSwift
MIT License
3.88k stars 494 forks source link

Communication with child view controller #65

Open jjochen opened 5 years ago

jjochen commented 5 years ago

Hello,

I can't wrap my head around how to communicate with a child view controller.

I have one trigger from the ParentViewController that is needed in the ChildViewModel and a second one from the ChildViewModel that should trigger some UI changes in the ParentViewController:

trigger1: ParentViewController (input)> ... (no idea)> ChildViewModel
trigger2: ChildViewModel (output)> ... (no idea)> ParentViewController

My code currently looks something like this:

final class ParentViewController: UIViewController {
    var viewModel: ParentViewModel?
    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        bindViewModel()
    }

    private func bindViewModel() {
        guard let viewModel = self.viewModel else {
            fatalError("View Model not set!")
        }

        let triggerToChild = rx.someTrigger

        let input = ParentViewModel.Input(triggerToChild: triggerToChild)

        let output = viewModel.transform(input: input)

        output.triggerFromChild
            .drive(rx.someProperty)
            .disposed(by: disposeBag)
    }
}

final class ParentViewModel: ViewModelType {
    struct Input {
       let triggerToChild: Driver<Void>
    }
    struct Output {
       let triggerFromChild: Driver<Void>
    }

    func transform(input: Input) -> Output {
        let triggerFromChild = ??? <===================

        return Output(triggerFromChild: triggerFromChild)
    }
}

final class ChildViewController: UIViewController {
    var viewModel: ChildViewModel?
    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        bindViewModel()
    }

    private func bindViewModel() {
        guard let viewModel = self.viewModel else {
            fatalError("View Model not set!")
        }

        let triggerFromParent = ??? <===================

        let input = ChildViewModel.Input(triggerFromParent: triggerFromParent)

        let output = viewModel.transform(input: input)

        output.triggerFromParent
            .drive(rx.someProperty)
            .disposed(by: disposeBag)
    }
}

final class ChildViewModel: ViewModelType {
    struct Input {
        let triggerFromParent: Driver<Void>
    }
    struct Output {
        let triggerToParent: Driver<Void>
    }

    func transform(input: Input) -> Output {
        let triggerToParent = rx.someTrigger
        return Output(triggerToParent: triggerToParent)
    }
}

Maybe someone could point me in the right direction? Thank You!

marktrobinson commented 4 years ago

I had the exact same thought 🤔 how does this ViewModalType work in that scenario?

marktrobinson commented 4 years ago

This article helps: https://medium.com/blablacar-tech/rxswift-mvvm-66827b8b3f10