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

RxFeedback使ってみた

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for yukatou yukatou
January 23, 2018

 RxFeedback使ってみた

Avatar for yukatou

yukatou

January 23, 2018
Tweet

Other Decks in Technology

Transcript

  1. RxFeedback • Try! Swift NYC (2017.11)
 Modern RxSwift Architectures by

    Krunoslav Zaher • https://github.com/NoTests/RxFeedback.swift • ݕࡧͯ͠΋υΩϡϝϯτগɻɻ
  2. typealias Feedback<State, Event> = (Observable<State>) -> Observable<Event> public static func

    system<State, Event>( initialState: State, reduce: @escaping (State, Event) -> State, feedback: Feedback<State, Event>... ) -> Observable<State> w JOJUJBM4UBUFॳظ4UBUFΛࢦఆ w SFEVDF&WFOUΛड͚औͬͯɺ4UBUFΛมߋ͢ΔॲཧΛఆٛ w GFFECBDL4UBUFͷมߋΛ΋ͱʹ6*Λมߋͨ͠Γɺ&WFOUΛൃՐͤ͞Δॲ ཧΛఆٛ Observable.systemPSDriver.systemͰݺͼग़͠ Interface
  3. State struct State { // ಡΈࠐΈϖʔδ਺ var loadPage: Int? =

    1 // ಡΈࠐΈத͔ var loading: Bool = false // ΞΠςϜϦετ var items: [Coin] = [] }
  4. Event enum Event { // ϦϑϨογϡ case refresh // ࣍ͷϖʔδΛϦΫΤετ

    case loadNextPage // Ϩεϙϯε case response([Coin]) }
  5. Reducer reduce: { (state: State, event: Event) -> State in

    switch event { case .refresh: var results = state results.loadPage = 1 results.loading = true results.items = [] return results case .loadNextPage: var results = state results.loadPage = (results.items.count / fetchCount) + 1 results.loading = true return results case .response(let items): var results = state results.loadPage = nil results.loading = false results.items += items return results } }
  6. Feedback feedback: bind(self) { me, state in let subscriptions: [Disposable]

    = [ // itemsΛUITableViewʹBind state.map { $0.items } .drive(me.tableView.rx.items(cellIdentifier: "Cell"))(me.configureCell), // loading ͕falseͰ͋Ε͹refreshControlΛఀࢭ state.map { $0.loading }.filter { !$0 } .drive(onNext: { _ in me.refreshControl.endRefreshing() }) ] let events: [Signal<Event>] = [ // RefreshControl͕มߋ͞ΕΕ͹refreshΠϕϯτΛൃՐͤ͞Δ me.refreshControl.rx.controlEvent(.valueChanged).asSignal().map { _ in Event.refresh }, // UITableViewΛఈ·ͰεΫϩʔϧͨ͠৔߹͸loadNextPageΠϕϯτΛൃՐͤ͞Δ state.flatMapLatest { state in if state.loading { return Signal.empty() } return me.tableView.rx.reachedBottom.map { _ in Event.loadNextPage } } ] return Bindings(subscriptions: subscriptions, events: events) }, react(query: { $0.loadPage }, effects: { page in // loadPage͕มߋ͞ΕΔ౓ʹݺ͹ΕΔ(nilͷ৔߹͸ݺ͹Εͳ͍) return api.fetch(page: page, limit: fetchCount) .asSignal(onErrorJustReturn: []) .map(Event.response) })
  7. ࢖ͬͯΈͨॴײ • State ͱ Event ͷઃܭ͕େࣄ • ໾ׂ͕໌֬ʹͳͬͯΔ͜ͱͰɺՄಡੑ͸ྑ͘ͳͬͨ • RxFeedback

    Λ࢖͏લͱൺ΂Δͱهड़ྔ͸ݮͬͨ • υΩϡϝϯτʢαϯϓϧʣ͕গͳ͍ͷͰਏ͔ͬͨ