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

ReactorKit Testability

USAMI Kosuke
February 15, 2019

ReactorKit Testability

USAMI Kosuke

February 15, 2019
Tweet

More Decks by USAMI Kosuke

Other Decks in Programming

Transcript

  1. ReactorKit Ͱςετ
    ͠΍͘͢͢Δ
    USAMI Kosuke
    Fenrir Inc.

    View Slide

  2. ࣗݾ঺հ
    • Ӊࠤݟެี @usamik26
    • ϑΣϯϦϧגࣜձࣾ
    • iOS ΞϓϦ։ൃ Swift / C# (Xamarin)

    View Slide

  3. தࠃʹߦ͖ͬͯͨ
    • ੒౎ ඈ࿛Պٕ
    • iOS ΞϓϦ։ൃϝϯόͱٕज़ަྲྀ
    • ੒౎ϝϯόʔ͸ ReactorKit Λ࢖ͬ
    ͍ͯͨ

    View Slide

  4. ReactorKit ͱ͸
    • RxSwift
    • Fluxʢ୯ํ޲ϑϩʔʣ
    • ܰྔͳϑϨʔϜϫʔΫ

    View Slide

  5. Design Goal
    • Testability : View ͱϩδοΫͷ෼཭
    • Start Small : ΞϓϦͷҰ෦͚ͩͰ΋ద༻Ͱ͖Δ
    • Less Typing : ίʔυΛෳࡶʹ͠ͳ͍

    View Slide

  6. Testability
    • ςετՄೳੑɺςετ༰қੑ
    • ࠓճ͸ Testability ʹ஫໨ͯ͠ ReactorKit ΛݟͯΈΔ

    View Slide

  7. ߏ੒ਤ

    View Slide

  8. View ͱ Reactor
    • View ͷ੹຿ (1)
    • UI ૢ࡞ → Action ͱͯ͠ Reactor ʹ౉͢
    • Reactor ͷ੹຿
    • Action → ॲཧΛߦ͍ State Λੜ੒͢Δ
    • View ͷ੹຿ (2)
    • State → UI ʹදࣔ͢Δ

    View Slide

  9. ੹຿ͷ෼཭
    • UIViewController ʹ͸ View ͷ੹຿͚ͩΛ࣋ͨͤΔ
    • Reactor ͸ผΦϒδΣΫτͱͯ͠෼཭ʢͳ͓ɺReactor ͸
    UIKit ͸࢖Θͳ͍ʣ
    • ͜ΕʹΑΓ Testability ͕޲্͢Δ
    • ࠓճ͸ಛʹ View ͷ Testability ΛݟͯΈΔ

    View Slide

  10. View ϓϩτίϧ
    class MyViewController: View {
    func bind(reactor: MyReactor) {
    // ͜͜Ͱ Reactor ͱͷόΠϯσΟϯάΛߦ͏
    // RxSwift Λ׆༻
    }
    }

    View Slide

  11. Reactor ϓϩτίϧ
    class MyReactor: Reactor {
    enum Action {
    case myAction
    case myActionWithArg(Int)
    }
    struct State {
    var myValue1 = ""
    var myValue2 = false
    }
    }

    View Slide

  12. View ͷόΠϯσΟϯά : Action
    func bind(reactor: MyReactor) {
    myButton.rx.tap
    .map { Reactor.Action.myAction }
    .bind(to: reactor.action)
    .disposed(by: self.disposeBag)
    ʢͳ͓ɺreactor.action ͸ ActionSubjectʣ

    View Slide

  13. View ͷόΠϯσΟϯά : State
    func bind(reactor: MyReactor) {
    reactor.state
    .map { $0.myValue1 }
    .bind(to: myLabel.rx.text)
    .disposed(by: self.disposeBag)
    ʢͳ͓ɺreactor.state ͸ Observableʣ

    View Slide

  14. Reactor ͷॲཧ : mutate()
    • Action Λड͚औͬͯ Observable Λฦ͢
    • ۩ମతͳॲཧʢWeb API ࣮ߦɺσʔλϕʔεΞΫηεɺͳͲʣ
    Λߦ͏ Observable Λੜ੒͢Δ
    • ࣮ࡍʹॲཧΛߦ͏͔Ͳ͏͔ͷ൑அͳͲ͸ Reactor ͷ໾໨
    • ͜ΕʹΑΓɺView ଆͰ͸ Action Λੜ੒͢Δ͔Ͳ͏͔Λ൑
    அ͠ͳ͍ͨΊɺView ͷ࣮૷͕όΠϯσΟϯά͚ͩͰ͢Ή

    View Slide

  15. Reactor ͷॲཧ : reduce()
    • Mutation ͱલͷ State Λड͚औͬͯ State Λฦ͢
    • ॲཧͷ݁Ռͱલͷঢ়ଶΛߟྀͯ࣍͠ͷঢ়ଶΛܾΊΔͷ͕໾໨
    • ͜ΕʹΑΓɺView ଆͰ͸લͷঢ়ଶΛߟྀ͢Δͱ͍ͬͨॲཧ͕
    ෆཁʹͳΔͨΊɺView ͷ࣮૷͕όΠϯσΟϯά͚ͩͰ͢Ή

    View Slide

  16. View ͷ୯ମςετΛߟ͑Δ
    • ୯ମςετͰԿΛ͢Δ΂͖͔ʁ
    • ʮͦͷΦϒδΣΫτͷ੹຿ΛՌ͍ͨͯ͠Δ͔ʯΛςετ͢Δ
    • View ͷ੹຿ (1) : UI ૢ࡞ → Action
    • View ͷ੹຿ (2) : State → UI දࣔ

    View Slide

  17. View ͷςετ : Action
    • ίʔυͰ UI ૢ࡞Λൃੜͤ͞Δ
    • myButton.sendActions(for .touchUpInside)
    • ͦͷ݁Ռͱͯ͠ɺReactor ʹ Action ΦϒδΣΫτ͕౉͞Ε
    ͨ͜ͱΛ֬ೝ͍ͨ͠
    • Ͳ͏΍ͬͯʁ ʹ Reactor ͷελϒΛ༻ҙ͢Ε͹͍͍
    • ࣮͸ ReactorKit Ͱ͸ελϒ͕͢Ͱʹ༻ҙ͞Ε͍ͯΔ

    View Slide

  18. View ͷςετ : Action
    func testMyAction() {
    let reactor = MyReactor()
    reactor.stub.isEnabled = true
    let view = MyView()
    view.reactor = reactor
    view.myButton.sendActions(for .touchUpInside)
    XCTAssertEqual(reactor.stub.actions.last, .myAction)
    }

    View Slide

  19. View ͷςετ : State
    • ΍͸Γ Reactor ͷελϒΛ׆༻͢Δ
    • ίʔυͰ Reactor ͷ State มԽΛى͜͢
    • ͦͷ݁Ռͱͯ͠ɺUI ද͕ࣔมߋ͞Εͨ͜ͱΛ֬ೝ͢Δ

    View Slide

  20. View ͷςετ : State
    func testMyAction() {
    let reactor = MyReactor()
    reactor.stub.isEnabled = true
    let view = MyView()
    view.reactor = reactor
    reactor.stub.state.value = MyReactor.State(myValue1: "abc")
    XCTAssertEqual(view.myLabel.text, "abc")
    }

    View Slide

  21. View ͷςετ·ͱΊ
    • Կ͕ςετͰ͖ͨͷ͔ʁ : View ͕੹຿ΛՌ͍ͨͯ͠Δ͜ͱ
    • View ͷ࣮૷ͱͯ͠͸όΠϯσΟϯά͕ͪΌΜͱͰ͖͍ͯΔ͜
    ͱ
    • ͦ΋ͦ΋ςετඞཁʁ : Testability ޲্ͷͨΊγϯϓϧ
    ͳΦϒδΣΫτʹͳͬͨ݁Ռɺ୯७͗ͯ͢ςετෆཁͰ͸ͱ͍
    ͏Ϩϕϧʹ
    • ࣮ࡍʹςετίʔυΛॻ͔͘Ͳ͏͔͸έʔεόΠέʔε

    View Slide

  22. Reactor ͷ୯ମςετʢུ֓ʣ
    • ʮͦͷΦϒδΣΫτͷ੹຿ΛՌ͍ͨͯ͠Δ͔ʯΛςετ͢Δ
    • Reactor ͷ੹຿ : Action → State
    • ίʔυͰ Action Λൃੜͤͯ͞ɺState มߋΛ֬ೝ͢Δ
    • Reactor ͸ View ΁ͷґଘ͕ͳ͍ͨΊɺಠཱͯ͠ςετՄೳ

    View Slide

  23. Reactor ͷ୯ମςετʢུ֓ʣ
    • Reactor ͷதͰ Web API ࣮ߦɺσʔλϕʔεΞΫηεɺͳ
    Ͳ͕͋Δͱ୯ମςετ͠ʹ͘͘ͳΔ
    • ͦ͜ͰɺͦΕΒΛ Service ͱͯ͠ Reactor ͷ֎ʹ੾Γग़͢
    • Service ΛελϒԽ͢Δ͜ͱͰ Reactor ͕୯ମςετՄೳ

    View Slide

  24. ·ͱΊ
    • ෳ਺ͷ੹຿Λ͕࣋ͪͪͳ UIViewController ʹ͍ͭͯɺ
    ReactorKit Ͱ View ͱ Reactor ʹ੹຿Λ෼཭ͨ͠
    • ͜ΕʹΑΓɺView ΍ Reactor ͕ςετՄೳʹͳͬͨ

    View Slide