状態管理とビューデータバインディング

 状態管理とビューデータバインディング

Swift, SwiftBond, MVVM, UI Stack

Acbf3391de0494432a92221ffe89f34e?s=128

yohei sugigami

November 24, 2015
Tweet

Transcript

  1. 2.
  2. 6.

    ঢ়ଶͱUIελοΫͰ੔ཧ͠Α͏ )PXUPpYBCBEVTFSJOUFSGBDF ೔ຊޠ༁όου6*Λվળ͢Δํ๏ʕ6*ͷʮͭͷঢ়ଶʯΛߟ͑Δ w ϒϥϯΫεςʔτ w ϩʔσΟϯάεςʔτ w ύʔγϟϧεςʔτ w

    Τϥʔεςʔτ w ཧ૝εςʔτ ̍ը໘Ͱଟ༷ͳঢ়ଶͱΓɺͦΕʹ߹Θͤͨը໘Λ දࣔ͢ΔϩδοΫ͕ෳࡶͩͱίʔυ͕ΧΦεܥʹ
  3. 7.

    ؅ཧͱ෼཭ ঢ়ଶΛ؅ཧ var state: State enum State { case Blank

    case Loading case Partial case Error case Ideal } 6*ελοΫຖʹϏϡʔΛ෦඼Խͯ͠෼཭ let blankView = BlankView() let loadingView = LoadingView() let partialView = PartialView() let errorView = ErrorView() let idealView = IdealView() or UITableView() etc … ͍ͩͿίʔυ੔ཧͰ͖ͦ͏
  4. 12.

    Code with SwiftBond final class RequestListViewModel<T: Identifier> { let items:

    DynamicArray<T> = DynamicArray([]) var requestListState = Dynamic<RequestListState>(.None) var noDataFirstViewHidden: Dynamic<Bool> { let a = indicatorViewHidden.map { $0 == false } let b = requestListFirstState.map { $0 == .Error } return reduce(a, b) { $0 || $1 == true } } var indicatorViewHidden: Dynamic<Bool> { let a = requestListFirstState.map { $0 != RequestListState.Requesting } let b = items.map { count($0) > 0 } return reduce(a, b) { $0 || $1 == true } } var retryViewHidden: Dynamic<Bool> { let a = requestListFirstState.map { $0 != RequestListState.Error } let b = items.map { count($0) > 0 } return reduce(a, b) { $0 || $1 == true } } 3FRVFTU4UBUFͱ*UFNTͷঢ়ଶͷΑΔڍಈΛએݴ

  5. 13.

    final class ContactsViewController: UIViewController { var tableViewDataSourceBond: UITableViewDataSourceBond<ContactCell>! let viewModel

    = ContactsViewModel() let indicatorView = InstantiateFromNib(IndicatorView) let retryView = InstantiateFromNib(RetryView) let noDataView = InstantiateFromNib(NoDataView) override func viewDidLoad() { super.viewDidLoad() viewModel.requestList.indicatorViewHidden ->> indicatorView.dynHidden viewModel.requestList.retryViewHidden ->> retryView.dynHidden viewModel.requestList.noDataFirstViewHidden ->> noDataView.dynHidden } 7JFX$POUSPMMFSͰ7JFX.PEFMͷ4XJGU#POEͱ7JFXΛ#JOEJOH Code with SwiftBond
  6. 14.

    final class RequestListViewModel<T: Identifier> { typealias RequestTask = Task<Progress, ResponseCollection<T>,

    NSError> func requestFirst(task: RequestTask) -> RequestTask { self.requestListState.value = .Requesting task.success { [weak self] (collection: ResponseCollection<T>) -> Void in self?.items.setArray(collection.items) self?.requestListState.value = .None }.failure { [weak self] (errorInfo: RequestTask.ErrorInfo) -> Void in self?.requestListState.value = .Error } return task } 3FRVFTUͷ։࢝ɺਖ਼ৗ׬ྃɺҎ্׬ྃͰ4BUFΛߋ৽ ਖ਼ৗ׬ྃ࣌ʹJUFNTΛߋ৽ Code with SwiftBond
  7. 15.

    final class RequestListViewModel<T: Identifier> { lazy var stateChangedObserver = Bond<RequestListState>

    { [weak self] state in switch state { case .Requesting: UIApplication.sharedApplication().networkActivityIndicatorVisible = true default: UIApplication.sharedApplication().networkActivityIndicatorVisible = false } } init() { requestListState ->| stateChangedObserver } OFUXPSL"DUJWJUZ*OEJDBUPS7JTJCMFΛ4UBUFͰ#JOEJOH Code with SwiftBond