35MM.COFFEEa site built for app makers
Profile
limboy

18 天前

Kickstater 的 ViewModel 设计的蛮有意思的,通过 inputs 和 outputs 来显式地标记 command 和 result。

定义 ViewModel

swift
public protocol ActitiviesViewModelInputs {
  func refresh()
  //...
}

public protocol ActivitiesViewModelOutputs {
  /// Emits an array of activities that should be displayed.
  var activities: Signal<[Activity], Never> { get }

  /// Emits a boolean that indicates if the activities are refreshing.
  var isRefreshing: Signal<Bool, Never> { get }
  
  //...
}

public protocol ActivitiesViewModelType {
  var inputs: ActitiviesViewModelInputs { get }
  var outputs: ActivitiesViewModelOutputs { get }
}

public final class ActivitiesViewModel: ActivitiesViewModelType, ActitiviesViewModelInputs,
  ActivitiesViewModelOutputs {
  public init() {
    // init
  }

  fileprivate let refreshProperty = MutableProperty(())
  public func refresh() {
    self.refreshProperty.value = ()
  }

  public let activities: Signal<[Activity], Never>
  public let isRefreshing: Signal<Bool, Never>

  public var inputs: ActitiviesViewModelInputs { return self }
  public var outputs: ActivitiesViewModelOutputs { return self }
}

使用 ViewModel

swift
final class ActivitiesViewController: UITableViewController {
  fileprivate let viewModel: ActivitiesViewModelType = ActivitiesViewModel()

  override func bindViewModel() {
    super.bindViewModel()
    self.refreshControl?.rac.refreshing = self.viewModel.outputs.isRefreshing
    self.viewModel.outputs.activities
      .observeForUI()
      .observeValues { [weak self] activities in
        self?.dataSource.load(activities: activities)
        self?.tableView.reloadData()
      }
    
  }
  //...
}