Search code examples
swiftmvvmreactive-programmingreactive-cocoareactivekit

Binding of model and viewModel in Swift Bond


I am using Swift Bond for two-way binding of view with viewModel. This is achieved by bidirectionalBind.

Question is: What is a common practice of binding a model with a viewModel and more specifically how would model know about changes made in viewModel. In ReactiveCocoa there is RACChannel to do that, so you can bind viewModel and model without changing types of model's properties.

Main goal is to keep model very simple with only primitive types like String, Int, Date and move Observable and Property types to viewModel.

Illustration:

import Bond
import ReactiveKit

struct Person {
    var name: String
    var age: Int
    var birthdate: Date
}

struct PersonViewModel {
    fileprivate var person: Person

    var name: Observable<String>
    var age: Observable<Int>
    var birthDate: Observable<Date>

    init(person: Person) {
        self.person = person

        // what should go here in order to bind properties???
    }
}

Solution

  • In order to bidirectionally bind your ViewModel and Model together you will need to have bindable properties inside of your Person Model which it sounds like you want to avoid. It is not possible to bind to a pure Int, String, or Date types.

    You could either modify your Model to use bindable properties, or you could architect a solution where your Model interacts with your ViewModel via some type of observable abstraction.

    biDirectionalBind is typically used to bind properties in your ViewModel layer with the View Layer in order to pass updates from the user's interactions back to the ViewModel, for example:

    let name = Property<String>("Fred")
    let textField = UITextField()
    name.bidirectionalBind(to: textField.bnd_text)