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

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

yohei sugigami
November 24, 2015

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

Swift, SwiftBond, MVVM, UI Stack

yohei sugigami

November 24, 2015
Tweet

More Decks by yohei sugigami

Other Decks in Technology

Transcript

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

    View full-size slide

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

    View full-size slide

  3. Sync Messenger iOS
    4XJGU .77. '31 1SPNJTF

    Ϟμϯͳཁૉٕज़Λશྗ౤ೖ

    View full-size slide

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

    View full-size slide

  5. ঢ়ଶͱUIελοΫͰ੔ཧ͠Α͏
    )PXUPpYBCBEVTFSJOUFSGBDF
    ೔ຊޠ༁όου6*Λվળ͢Δํ๏ʕ6*ͷʮͭͷঢ়ଶʯΛߟ͑Δ
    w ϒϥϯΫεςʔτ
    w ϩʔσΟϯάεςʔτ
    w ύʔγϟϧεςʔτ
    w Τϥʔεςʔτ
    w ཧ૝εςʔτ
    ̍ը໘Ͱଟ༷ͳঢ়ଶͱΓɺͦΕʹ߹Θͤͨը໘Λ
    දࣔ͢ΔϩδοΫ͕ෳࡶͩͱίʔυ͕ΧΦεܥʹ

    View full-size slide

  6. ؅ཧͱ෼཭
    ঢ়ଶΛ؅ཧ
    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 …
    ͍ͩͿίʔυ੔ཧͰ͖ͦ͏

    View full-size slide

  7. ঢ়ଶͱը໘ΛࣗಈͰ࿈ಈ͍ͨ͠ʂ
    ঢ়ଶ͕มΘΔͱ6*ελοΫͷදࣔ΋
    ࿈ಈͯࣗ͠ಈͰը໘ͷදࣔ΋มߋ͍ͨ͠
    state = .Blank
    blankView.hidden = false

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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


    View full-size slide

  12. final class ContactsViewController: UIViewController {
    var tableViewDataSourceBond: UITableViewDataSourceBond!
    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

    View full-size slide

  13. final class RequestListViewModel {
    typealias RequestTask = Task, NSError>
    func requestFirst(task: RequestTask) -> RequestTask {
    self.requestListState.value = .Requesting
    task.success { [weak self] (collection: ResponseCollection) -> 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

    View full-size slide

  14. final class RequestListViewModel {
    lazy var stateChangedObserver = Bond { [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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  17. Enjoy happy coding!

    View full-size slide