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

RxFeedback使ってみた

95039a6020131a41304dcb07cb2180ff?s=47 yukatou
January 23, 2018

 RxFeedback使ってみた

95039a6020131a41304dcb07cb2180ff?s=128

yukatou

January 23, 2018
Tweet

Transcript

  1. RxFeedback࢖ͬͯΈͨ Nagoya iOS Meetup Vol.1 2018.1
 @katoyan_

  2. ࣗݾ঺հ • @katoyan_ • ͓ͱͱ໊͠ݹ԰ʹUλʔϯ͖ͯ͠·ͨ͠ • ࢓ࣄ
 iOS, αʔόαΠυ •

    ࠷ۙ͸Ծ૝௨՟ʹϋϚͬͯ·͢
  3. RxSwift࢖ͬͯ·͔͢ʁ

  4. None
  5. RxSwiftͰ։ൃ͢Δͱ͖
 ΞʔΩςΫνϟͬͯԿ͕ྑ͍ΜͩΖ͏ʁ MVVM? Flux/Redux? Clean Architecture?

  6. None
  7. IUUQTHJUIVCDPNCFFUIWFO3Y4XJGU$IJOFTF%PDVNFOUBUJPO

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

    Krunoslav Zaher • https://github.com/NoTests/RxFeedback.swift • ݕࡧͯ͠΋υΩϡϝϯτগɻɻ
  9. RxFeedbackͷߏ଄ The simplest architecture for RxSwift IUUQTHJUIVCDPN/P5FTUT3Y'FFECBDLTXJGU

  10. ͋ΕʁReduxʹࣅͯΔؾ͕͢Δ

  11. IUUQTBDBEFNZSFBMNJPQPTUTUSZTXJGUOZDLSVOPTMBW[BIFSNPEFSOSYTXJGUBSDIJUFDUVSFT 3FEVY͸"QQMJDBUJPO-FWFMͰͭͷେ͖ͳ4UBUF͕ඞཁɻ 3Y'FFECBDL͸7JFX$POUSPMMFS୯ҐͰ4UBUFΛ࣋ͭ͜ͱ΋Մೳɻ ఻ൖίετ͕Լ͕Δ

  12. 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
  13. None
  14. RxFeedbackͰΞϓϦΛ࡞ͬͯΈͨ  Ծ૝௨՟"1*ΛϦΫΤετͯ݁͠ՌΛ 6*5BCMF7JFXͰදࣔ  SFGSFTI$POUSPMMͰ݁ՌΛϦϑϨογϡ  6*5BCMF7JFXͷҰ൪Լ·ͰεΫϩʔϧͨ͠ Βଓ͖ͷσʔλΛऔಘ

  15. State struct State { // ಡΈࠐΈϖʔδ਺ var loadPage: Int? =

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

    case loadNextPage // Ϩεϙϯε case response([Coin]) }
  17. 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 } }
  18. 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) })
  19. DEMO

  20. ࢖ͬͯΈͨॴײ • State ͱ Event ͷઃܭ͕େࣄ • ໾ׂ͕໌֬ʹͳͬͯΔ͜ͱͰɺՄಡੑ͸ྑ͘ͳͬͨ • RxFeedback

    Λ࢖͏લͱൺ΂Δͱهड़ྔ͸ݮͬͨ • υΩϡϝϯτʢαϯϓϧʣ͕গͳ͍ͷͰਏ͔ͬͨ
  21. ͓ΘΓ https://github.com/yukatou/CryptoChecker-RxFeedback