Pro Yearly is on sale from $80 to $50! »

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

Acbf3391de0494432a92221ffe89f34e?s=47 yohei sugigami
November 24, 2015

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

Swift, SwiftBond, MVVM, UI Stack

Acbf3391de0494432a92221ffe89f34e?s=128

yohei sugigami

November 24, 2015
Tweet

Transcript

  1. ঢ়ଶ؅ཧͱ ϏϡʔσʔλόΠϯσΟϯά yohei SUGIGAMI 11/23 potatotips@FiNC

  2. None
  3. Sync Messenger 8FC %FTLUPQ"QQ "OESPJE BOEJ04 ϏδωείϛϡχέʔγϣϯಛԽϝοηʔδϯάαʔϏε

  4. Sync Messenger iOS 4XJGU .77. '31 1SPNJTF
 Ϟμϯͳཁૉٕज़Λશྗ౤ೖ

  5. ΞϓϦͷίʔυ ෳࡶʹͳ͍ͬͯ·ͤΜ͔

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

    Τϥʔεςʔτ w ཧ૝εςʔτ ̍ը໘Ͱଟ༷ͳঢ়ଶͱΓɺͦΕʹ߹Θͤͨը໘Λ දࣔ͢ΔϩδοΫ͕ෳࡶͩͱίʔυ͕ΧΦεܥʹ
  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 … ͍ͩͿίʔυ੔ཧͰ͖ͦ͏
  8. ঢ়ଶͱը໘ΛࣗಈͰ࿈ಈ͍ͨ͠ʂ ঢ়ଶ͕มΘΔͱ6*ελοΫͷදࣔ΋ ࿈ಈͯࣗ͠ಈͰը໘ͷදࣔ΋มߋ͍ͨ͠ state = .Blank blankView.hidden = false 㱺

  9. ͦΕ ϏϡʔσʔλόΠϯσΟϯάͰʂ with SwiftBond

  10. 4UBUF3FRVFTUJOH 4UBUF&SSPS JUFNT<> 4UBUF/POF *OEJDBUPS7JFX 3FUSZ7JFX /P%BUB7JFX ViewDataBinding

  11. ViewDataBinding 4UBUF3FRVFTUJOH 4UBUF&SSPS JUFNT<JUFN JUFN JUFN ʜ> 4UBUF/POF *OEJDBUPS7JFX 3FUSZ7JFX

    /P%BUB7JFX
  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ͷঢ়ଶͷΑΔڍಈΛએݴ

  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
  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
  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
  16. ·ͱΊ ɾΞϓϦΛঢ়ଶͱελοΫͰ؅ཧ ɾ͋Δঢ়ଶʹ͓͚Δը໘දࣔϩδοΫΛ ɹએݴతʹهड़ ɾঢ়ଶ͕มԽͨ͠Βࣗಈతʹը໘දࣔ΋ ɹมߋ͞ΕΔΑ͏ʹ

  17. ߋʹৄࡉΛQiitaʹ΋ॻ͖·ͨ͠ IUUQRJJUBDPNTVTJFZZJUFNTBGCCEGG

  18. Enjoy happy coding!