try! ReactorKit

try! ReactorKit

ReactorKit Meetup Japan at Wantedly, Inc.
日本初 ReactorKit のコミュニティーイベント開催。作者来日で特別講演
https://wantedly.connpass.com/event/90261/

5eee847529e8f5ec2f634a85075fd5aa?s=128

Satoshi Hachiya

June 28, 2018
Tweet

Transcript

  1. try! ReactorKit 2018.06.28 - ReactorKit Meetup Japan at Wantedly, Inc.

    Satoshi Hachiya - @jpmartha_jp
  2. Satoshi Hachiya - @jpmartha_jp working at

  3. Welcome to Japan!

  4. I've met Suyeol Jeon before

  5. try! Swift NYC 2017 (Sep. 2017)

  6. WWDC 2018 (Jun. 2018)

  7. And then, I met ReactorKit

  8. ReactorKit • I just started learning RxSwift and ReactorKit •

    The documents are easy to understand • The examples are abundant # Anytime you ready!
  9. ReactorKit Examples https://github.com/ReactorKit/ReactorKit#examples

  10. ReactorKitΛֶͿγϦʔζ (Japanese) https://qiita.com/yusuga/items/e793963ff51ee493497a

  11. !

  12. try! ReactorKit

  13. Installing ReactorKit • Use CocoaPods • Create reactors • ...

  14. Using ReactorKit ViewController - Reactor ViewController - Reactor Cell -

    Reactor ...
  15. Reactor

  16. ActionʢΞΫγϣϯʣ enum Action { case increase // ૿Ճ case decrease

    // ݮগ }
  17. MutationʢมԽʣ enum Mutation { case increaseValue // ஋Λ૿΍͢ case decreaseValue

    // ஋ΛݮΒ͢ ... }
  18. Stateʢঢ়ଶʣ struct State { var value: Int // ஋ ...

    }
  19. initialStateʢঢ়ଶͷॳظ஋ʣ let initialState: State init() { self.initialState = State( value:

    0, // 0 ͔Β͸͡·Δ ... ) }
  20. View

  21. ViewController func bind(reactor: CounterViewReactor) { increaseButton.rx.tap .map { Reactor.Action.increase }

    .bind(to: reactor.action) .disposed(by: disposeBag) ... }
  22. Easy

  23. Introducing failure cases for beginners

  24. Run!

  25. ... No action

  26. Need to set `reactor` property

  27. viewController.reactor = MyViewReactor() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey:

    Any]?) -> Bool { let viewController = self.window?.rootViewController as! MyViewController viewController.reactor = MyViewReactor() return true }
  28. Other case using UICollectionView

  29. Runtime Error

  30. Runtime Error class MyViewController: UIViewController, StoryboardView { ... func bind(reactor:

    MyViewReactor) { collectionView.rx.contentOffset .map { _ in Reactor.Action.increase } .bind(to: reactor.action) .disposed(by: disposeBag) } ... }
  31. https://github.com/ReactiveX/RxSwift/issues/1587

  32. + UICollectionViewDelegate class PageMenuViewController: UIViewController, UICollectionViewDelegate, StoryboardView { ... func

    bind(reactor: MyViewReactor) { collectionView.rx.contentOffset .map { _ in Reactor.Action.increase } .bind(to: reactor.action) .disposed(by: disposeBag) } ... }
  33. It worked!

  34. Review

  35. Basic Concept

  36. Unidirectional Data Flow

  37. View ➡ Action func bind(reactor: CounterViewReactor) { increaseButton.rx.tap .map {

    Reactor.Action.increase } .bind(to: reactor.action) .disposed(by: disposeBag) ... }
  38. Action ➡ Mutation func mutate(action: Action) -> Observable<Mutation> { switch

    action { case .increase: return Observable.concat([ ..., Observable.just(Mutation.increaseValue).delay(0.5, scheduler: MainScheduler.instance), ..., ]) case .decrease: ... } }
  39. Mutation State func reduce(state: State, mutation: Mutation) -> State {

    var state = state switch mutation { case .increaseValue: state.value += 1 ... return state }
  40. State ➡ View func bind(reactor: CounterViewReactor) { ... reactor.state.map {

    $0.value } .distinctUntilChanged() .map { "\($0)" } .bind(to: valueLabel.rx.text) .disposed(by: disposeBag) ... }
  41. Good readability of the code • ReactorKit makes it easier

    to... • separate the responsibílities • manage the state of the views • manage the data flow
  42. try! ReactorKit

  43. Thanks!