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

try! ReactorKit

try! ReactorKit

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

Satoshi Hachiya

June 28, 2018
Tweet

More Decks by Satoshi Hachiya

Other Decks in Programming

Transcript

  1. try! ReactorKit
    2018.06.28 - ReactorKit Meetup Japan at Wantedly, Inc.
    Satoshi Hachiya - @jpmartha_jp

    View full-size slide

  2. Satoshi Hachiya - @jpmartha_jp
    working at

    View full-size slide

  3. Welcome to Japan!

    View full-size slide

  4. I've met Suyeol Jeon before

    View full-size slide

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

    View full-size slide

  6. WWDC 2018 (Jun. 2018)

    View full-size slide

  7. And then, I met ReactorKit

    View full-size slide

  8. ReactorKit
    • I just started learning RxSwift and ReactorKit
    • The documents are easy to understand
    • The examples are abundant
    #
    Anytime you ready!

    View full-size slide

  9. ReactorKit Examples
    https://github.com/ReactorKit/ReactorKit#examples

    View full-size slide

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

    View full-size slide

  11. try! ReactorKit

    View full-size slide

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

    View full-size slide

  13. Using ReactorKit
    ViewController - Reactor
    ViewController - Reactor
    Cell - Reactor
    ...

    View full-size slide

  14. ActionʢΞΫγϣϯʣ
    enum Action {
    case increase // ૿Ճ
    case decrease // ݮগ
    }

    View full-size slide

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

    View full-size slide

  16. Stateʢঢ়ଶʣ
    struct State {
    var value: Int // ஋
    ...
    }

    View full-size slide

  17. initialStateʢঢ়ଶͷॳظ஋ʣ
    let initialState: State
    init() {
    self.initialState = State(
    value: 0, // 0 ͔Β͸͡·Δ
    ...
    )
    }

    View full-size slide

  18. ViewController
    func bind(reactor: CounterViewReactor) {
    increaseButton.rx.tap
    .map { Reactor.Action.increase }
    .bind(to: reactor.action)
    .disposed(by: disposeBag)
    ...
    }

    View full-size slide

  19. Introducing failure cases
    for beginners

    View full-size slide

  20. ... No action

    View full-size slide

  21. Need to set `reactor` property

    View full-size slide

  22. viewController.reactor = MyViewReactor()
    func application(_ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let viewController = self.window?.rootViewController as! MyViewController
    viewController.reactor = MyViewReactor()
    return true
    }

    View full-size slide

  23. Other case
    using UICollectionView

    View full-size slide

  24. Runtime Error

    View full-size slide

  25. 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)
    }
    ...
    }

    View full-size slide

  26. https://github.com/ReactiveX/RxSwift/issues/1587

    View full-size slide

  27. + 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)
    }
    ...
    }

    View full-size slide

  28. Basic Concept

    View full-size slide

  29. Unidirectional Data Flow

    View full-size slide

  30. View

    Action
    func bind(reactor: CounterViewReactor) {
    increaseButton.rx.tap
    .map { Reactor.Action.increase }
    .bind(to: reactor.action)
    .disposed(by: disposeBag)
    ...
    }

    View full-size slide

  31. Action

    Mutation
    func mutate(action: Action) -> Observable {
    switch action {
    case .increase:
    return Observable.concat([
    ...,
    Observable.just(Mutation.increaseValue).delay(0.5, scheduler: MainScheduler.instance),
    ...,
    ])
    case .decrease:
    ...
    }
    }

    View full-size slide

  32. Mutation State
    func reduce(state: State, mutation: Mutation) -> State {
    var state = state
    switch mutation {
    case .increaseValue:
    state.value += 1
    ...
    return state
    }

    View full-size slide

  33. State

    View
    func bind(reactor: CounterViewReactor) {
    ...
    reactor.state.map { $0.value }
    .distinctUntilChanged()
    .map { "\($0)" }
    .bind(to: valueLabel.rx.text)
    .disposed(by: disposeBag)
    ...
    }

    View full-size slide

  34. Good readability of the code
    • ReactorKit makes it easier to...
    • separate the responsibílities
    • manage the state of the views
    • manage the data flow

    View full-size slide

  35. try! ReactorKit

    View full-size slide