Engineering

Simple Interface for ViewModel

I've read some articles about Flux architecture.
One of Flux architecture's merit will be clear input and output. It like Actions and States.

So, I thought the idea about importing this merit to ViewModel.
Defining states is hard for current implementations.
But, Grouping inputs is not hard.

protocol ViewModelWireframe : class {
  associatedtype Action
  func run(_ action: Action)
}

Implemented sample code.
When you request run action, call run(_ action).
ViewModel can receive action in one function only.

final class ViewModel : ViewModelWireframe {

  enum Action {
    case like(partnerIdentifier: String)
    case nope(partnerIdentifier: String)
  }

  // Outputs
  let showComplete = PublishSubject<Void>()
  let processing = PublishSubject<Void>()

  // Input
  func run(_ action: Action) {

    switch action {
    case let .like(partnerIdentifier):
      // Do something
      break
    case let .nope(partnerIdentifier):
      // Do someting
      break
    }
  }
}

If you using RxSwift, the following code would be helpful binding.

// Optional Extension
extension ViewModelWireframe {

  public var action: AnyObserver<Action> {
    return AnyObserver<Action> { [weak self] e in

      guard let `self` = self else { return }

      switch e {
      case .next(let action):
        self.run(action)
      case .error(let error):
        assertionFailure("Don't send error \(error)")
        break
      case .completed:
        break
      }
    }
  }
}