Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Avatar for yohei sugigami yohei sugigami
November 24, 2015

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

Swift, SwiftBond, MVVM, UI Stack

Avatar for yohei sugigami

yohei sugigami

November 24, 2015
Tweet

More Decks by yohei sugigami

Other Decks in Technology

Transcript

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

    Τϥʔεςʔτ w ཧ૝εςʔτ ̍ը໘Ͱଟ༷ͳঢ়ଶͱΓɺͦΕʹ߹Θͤͨը໘Λ දࣔ͢ΔϩδοΫ͕ෳࡶͩͱίʔυ͕ΧΦεܥʹ
  2. ؅ཧͱ෼཭ ঢ়ଶΛ؅ཧ 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 … ͍ͩͿίʔυ੔ཧͰ͖ͦ͏
  3. 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ͷঢ়ଶͷΑΔڍಈΛએݴ

  4. 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
  5. 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
  6. 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