Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
Hello, ReactorKit! 👋
Suyeol Jeon https://github.com/devxoul
Jeon Suyeol
StyleShare Inc.
Open Source Lover
Then
URLNavigator
RxSwift
ObjectMapper
Why?
Why?
Massive View Controller
Why?
Massive View Controller
RxSwift State Managing
Massive View Controller
https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MV...
Massive View Controller
https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MV...
Massive View Controller
🙁
https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/...
RxSwift State Managing
Cyclic Data Dependencies
RxSwift State Managing
currentValue increaseValue()
RxSwift State Managing
currentValue increaseValue()
last state
RxSwift State Managing
currentValue increaseValue()
last state
result
RxSwift State Managing
Cyclic Data Dependencies
RxSwift State Managing
Cyclic Data Dependencies
Pagination
List operation
Value update
...
RxSwift State Managing
After a while...
RxSwift State Managing
After a while...
Variable<Int>
PublishSubject<Int>
PublishRelay<[Item]>
Variable<User>
BehaviorSubj...
I wanted to...
1. Avoid Massive View Controller
I wanted to...
1. Avoid Massive View Controller
2. Take advantages of RxSwift
I wanted to...
1. Avoid Massive View Controller
2. Take advantages of RxSwift
3. Manage states gracefully
ReactorKit
ReactorKit can...
1. Avoid Massive View Controller ✅
ReactorKit can...
1. Avoid Massive View Controller ✅
Separates responsibilities of view and logic
ReactorKit can...
1. Avoid Massive View Controller ✅
Separates responsibilities of view and logic
View Controller becomes ...
ReactorKit can...
2. Take advantages of RxSwift ✅
ReactorKit can...
2. Take advantages of RxSwift ✅
Based on RxSwift
ReactorKit can...
2. Take advantages of RxSwift ✅
Based on RxSwift
All of RxSwift features are available
ReactorKit can...
3. Manage states gracefully ✅
ReactorKit can...
3. Manage states gracefully ✅
Unidirectional data flow
ReactorKit can...
3. Manage states gracefully ✅
Unidirectional data flow
Modify states only in reduce()
ReactorKit can...
3. Manage states gracefully ✅
Unidirectional data flow
Modify states only in reduce()
State management b...
ReactorKit can...
Be the future
~1.1K ⭐
~50K downloads
~900 apps
https://starcharts.herokuapp.com/ReactorKit/ReactorKit
ReactorKit can...
Be the future
~1.1K ⭐
~50K downloads
~900 apps
https://starcharts.herokuapp.com/ReactorKit/ReactorKit
Basic Concept
Basic Concept
Abstraction of User Interaction
Abstraction of View State
Basic Concept
Renders view states
Handles user interactions
ViewController,Cell,...
Basic Concept
protocol View {
associatedtype Reactor
var disposeBag: DisposeBag
// gets called when
// self.reactor is cha...
Basic Concept
protocol StoryboardView {
associatedtype Reactor
var disposeBag: DisposeBag
// gets called when
// the view ...
Basic Concept
Performs business logic
Manages states
Corresponds to view
Basic Concept
protocol Reactor {
associatedtype Action
associatedtype Mutation
associatedtype State
var initialState: Stat...
Basic Concept
Based on RxSwift
Data Flow
Data Flow
Data Flow
Action → State ❌
Data Flow
Action → Mutation → State
Data Flow
Action → Mutation → State
State manipulator
Data Flow
State manipulator
Async-able
Action → Mutation → State
Data Flow
State manipulator
Async-able
Not exposed to view
Action → Mutation → State
Data Flow
(Action) -> Observable<Mutation>
(State, Mutation) -> State
Data Flow
Data Flow
class ProfileViewReactor: Reactor {
enum Action {
}
struct State {
}
}
Data Flow
class ProfileViewReactor: Reactor {
enum Action {
case follow // user interaction
}
struct State {
}
}
Data Flow
class ProfileViewReactor: Reactor {
enum Action {
case follow // user interaction
}
struct State {
var isFollowi...
Data Flow
class ProfileViewReactor: Reactor {
enum Action {
case follow // user interaction
}
struct State {
var isFollowi...
Data Flow
class ProfileViewReactor: Reactor {
enum Action {
case follow // user interaction
}
struct State {
var isFollowi...
Data Flow
class ProfileViewReactor: Reactor {
enum Action {
case follow // user interaction
}
enum Mutation {
}
struct Sta...
Data Flow
class ProfileViewReactor: Reactor {
enum Action {
case follow // user interaction
}
enum Mutation {
case setFoll...
Data Flow
Data Flow
Tap follow button
Data Flow
Action.follow
Data Flow
Action.follow
Data Flow
UserService.follow()
Data Flow
UserService
Data Flow
Observable<Bool>
Data Flow
Data Flow
Mutation.setFollowing(true)
Data Flow
Mutation.setFollowing(true)
Data Flow
isFollowing = true
Data Flow
Update
follow button
Data Flow
More Examples
More Examples
Advanced
View Communications
Testing View and Reactor
View Communications
ProfileViewController
ProfileViewReactor
View Communications
UICollectionView
ProfileViewController
ProfileViewReactor
View Communications
UICollectionView
ProfileViewController
ProfileViewReactor
UserCell
View Communications
Passing user data
Observing button tap
View Communications - Passing user data
ProfileView
Controller
UserCell
ProfileView
Reactor
View Communications - Passing user data
ProfileView
Controller
UserCell
ProfileView
Reactor
1.User
View Communications - Passing user data
ProfileView
Controller
UserCell
ProfileView
Reactor
1.User
2.User
View Communications - Passing user data
// ProfileViewReactor
struct State {
}
View Communications - Passing user data
// ProfileViewReactor
struct State {
var user: User?
}
View Communications - Passing user data
// ProfileViewReactor
struct State {
var user: User?
}
// ProfileViewController
le...
View Communications - Passing user data
// ProfileViewReactor
struct State {
var user: User?
}
// ProfileViewController
le...
View Communications - Passing user data
// ProfileViewReactor
struct State {
var user: User?
}
// ProfileViewController
le...
View Communications - Observing button tap
ProfileView
Controller
UserCell
ProfileView
Reactor
View Communications - Observing button tap
ProfileView
Controller
UserCell
ProfileView
Reactor
1.rx.tap
View Communications - Observing button tap
ProfileView
Controller
UserCell
ProfileView
Reactor
2.Action.follow
1.rx.tap
View Communications - Observing button tap
ProfileView
Controller
UserCell
ProfileView
Reactor
2.Action.follow
1.rx.tap Re...
View Communications - Observing button tap
// UserCell
extension Reactive where Base: UserCell {
}
View Communications - Observing button tap
// UserCell
extension Reactive where Base: UserCell {
var buttonTap: ControlEve...
View Communications - Observing button tap
// UserCell
extension Reactive where Base: UserCell {
var buttonTap: ControlEve...
View Communications - Observing button tap
// UserCell
extension Reactive where Base: UserCell {
var buttonTap: ControlEve...
View Communications - Observing button tap
// UserCell
extension Reactive where Base: UserCell {
var buttonTap: ControlEve...
View Communications - Observing button tap
// UserCell
extension Reactive where Base: UserCell {
var tap: ControlEvent<Voi...
View Communications - Observing button tap
// UserCell
extension Reactive where Base: UserCell {
var tap: ControlEvent<Voi...
View Communications - Observing button tap
// UserCell
extension Reactive where Base: UserCell {
var tap: ControlEvent<Voi...
View Communications
UICollectionView
ProfileViewController
ProfileViewReactor
UserCell
View Communications
UICollectionView
ProfileViewController
ProfileViewReactor
UserCell
UserCellReactor
View Communications - Passing user data
ProfileView
Controller
UserCell
ProfileView
Reactor
View Communications - Passing user data
ProfileView
Controller
UserCell
ProfileView
Reactor
UserCell
Reactor
View Communications - Passing user data
ProfileView
Controller
UserCell
ProfileView
Reactor
1.CellReactor
UserCell
Reactor
View Communications - Passing user data
ProfileView
Controller
UserCell
ProfileView
Reactor
1.CellReactor
2.CellReactor
Us...
View Communications - Passing user data
ProfileView
Controller
UserCell
ProfileView
Reactor
1.CellReactor
2.CellReactor
Us...
View Communications - Passing user data
// ProfileViewReactor
struct State {
var user: User?
}
View Communications - Passing user data
// ProfileViewReactor
struct State {
var user: User?
var userCellReactor: UserCell...
View Communications - Passing user data
// ProfileViewReactor
struct State {
var user: User?
var userCellReactor: UserCell...
View Communications - Passing user data
// ProfileViewReactor
struct State {
var user: User?
var userCellReactor: UserCell...
Testing View and Reactor
What to test?
View
Reactor
Testing View and Reactor
What to test?
View
Action: on user interaction → action sent?
Reactor
Testing View and Reactor
What to test?
View
Action: on user interaction → action sent?
State: on state change → view updat...
Testing View and Reactor
What to test?
View
Action: on user interaction → action sent?
State: on state change → view updat...
Testing View and Reactor
How to test?
Testing View and Reactor
How to test?
Reactor.stub()
Testing View and Reactor
How to test?
Reactor.stub()
state: set fake state
Testing View and Reactor
How to test?
Reactor.stub()
state: set fake state
action: send fake action
Testing View and Reactor
How to test?
Reactor.stub()
state: set fake state
action: send fake action
actions: log received ...
Testing View and Reactor - View Action
Testing View and Reactor - View Action
When:
follow button taps
Then:
sends follow action
Testing View and Reactor - View Action
// given
let reactor = ProfileViewReactor()
// when
// then
Testing View and Reactor - View Action
// given
let reactor = ProfileViewReactor()
reactor.stub.isEnabled = true
// when
/...
Testing View and Reactor - View Action
// given
let reactor = ProfileViewReactor()
reactor.stub.isEnabled = true
reactor.s...
Testing View and Reactor - View Action
// given
let reactor = ProfileViewReactor()
reactor.stub.isEnabled = true
reactor.s...
Testing View and Reactor - View Action
// given
let reactor = ProfileViewReactor()
reactor.stub.isEnabled = true
reactor.s...
Testing View and Reactor - View Action
// given
let reactor = ProfileViewReactor()
reactor.stub.isEnabled = true
reactor.s...
Testing View and Reactor - View Action
// given
let reactor = ProfileViewReactor()
reactor.stub.isEnabled = true
reactor.s...
Testing View and Reactor - View State
When:
following the user
Then:
button is selected
Testing View and Reactor - View State
// given
let cellReactor = UserCellReactor()
// when
// then
Testing View and Reactor - View State
// given
let cellReactor = UserCellReactor()
cellReactor.stub.isEnabled = true
// wh...
Testing View and Reactor - View State
// given
let cellReactor = UserCellReactor()
cellReactor.stub.isEnabled = true
let c...
Testing View and Reactor - View State
// given
let cellReactor = UserCellReactor()
cellReactor.stub.isEnabled = true
let c...
Testing View and Reactor - View State
// given
let cellReactor = UserCellReactor()
cellReactor.stub.isEnabled = true
let c...
Testing View and Reactor - Reactor State
When:
receive follow action
Then:
update following state
ProfileView
Reactor
Testing View and Reactor - Reactor State
// given
let reactor = ProfileViewReactor()
// when
// then
Testing View and Reactor - Reactor State
// given
let reactor = ProfileViewReactor()
// when
reactor.action.onNext(.follow...
Testing View and Reactor - Reactor State
// given
let reactor = ProfileViewReactor()
// when
reactor.action.onNext(.follow...
Future Ideas
Development
Documentation
Community
Development
Testing Support
SectionReactor
AlertReactor
ModelReactor
Plugins
...
Nested stub
Dummy reactor
...
Building Ex...
Documentation
Best Practices
Translations
Code-level Documentation
Community
RxSwift Slack #reactorkit (English)
https://rxswift-slack.herokuapp.com
Swift Korea Slack #reactorkit (Korean)
h...
https://reactorkit.io
Próxima SlideShare
Cargando en…5
×

Hello, ReactorKit 

1.293 visualizaciones

Publicado el

ReactorKit Meetup Japan

Publicado en: Ingeniería
  • Sé el primero en comentar

Hello, ReactorKit 

  1. 1. Hello, ReactorKit! 👋 Suyeol Jeon https://github.com/devxoul
  2. 2. Jeon Suyeol StyleShare Inc. Open Source Lover Then URLNavigator RxSwift ObjectMapper
  3. 3. Why?
  4. 4. Why? Massive View Controller
  5. 5. Why? Massive View Controller RxSwift State Managing
  6. 6. Massive View Controller https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html
  7. 7. Massive View Controller https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html
  8. 8. Massive View Controller 🙁 https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html
  9. 9. RxSwift State Managing Cyclic Data Dependencies
  10. 10. RxSwift State Managing currentValue increaseValue()
  11. 11. RxSwift State Managing currentValue increaseValue() last state
  12. 12. RxSwift State Managing currentValue increaseValue() last state result
  13. 13. RxSwift State Managing Cyclic Data Dependencies
  14. 14. RxSwift State Managing Cyclic Data Dependencies Pagination List operation Value update ...
  15. 15. RxSwift State Managing After a while...
  16. 16. RxSwift State Managing After a while... Variable<Int> PublishSubject<Int> PublishRelay<[Item]> Variable<User> BehaviorSubject<String> Variable<String>
  17. 17. I wanted to... 1. Avoid Massive View Controller
  18. 18. I wanted to... 1. Avoid Massive View Controller 2. Take advantages of RxSwift
  19. 19. I wanted to... 1. Avoid Massive View Controller 2. Take advantages of RxSwift 3. Manage states gracefully
  20. 20. ReactorKit
  21. 21. ReactorKit can... 1. Avoid Massive View Controller ✅
  22. 22. ReactorKit can... 1. Avoid Massive View Controller ✅ Separates responsibilities of view and logic
  23. 23. ReactorKit can... 1. Avoid Massive View Controller ✅ Separates responsibilities of view and logic View Controller becomes simple
  24. 24. ReactorKit can... 2. Take advantages of RxSwift ✅
  25. 25. ReactorKit can... 2. Take advantages of RxSwift ✅ Based on RxSwift
  26. 26. ReactorKit can... 2. Take advantages of RxSwift ✅ Based on RxSwift All of RxSwift features are available
  27. 27. ReactorKit can... 3. Manage states gracefully ✅
  28. 28. ReactorKit can... 3. Manage states gracefully ✅ Unidirectional data flow
  29. 29. ReactorKit can... 3. Manage states gracefully ✅ Unidirectional data flow Modify states only in reduce()
  30. 30. ReactorKit can... 3. Manage states gracefully ✅ Unidirectional data flow Modify states only in reduce() State management became easy
  31. 31. ReactorKit can... Be the future ~1.1K ⭐ ~50K downloads ~900 apps https://starcharts.herokuapp.com/ReactorKit/ReactorKit
  32. 32. ReactorKit can... Be the future ~1.1K ⭐ ~50K downloads ~900 apps https://starcharts.herokuapp.com/ReactorKit/ReactorKit
  33. 33. Basic Concept
  34. 34. Basic Concept Abstraction of User Interaction Abstraction of View State
  35. 35. Basic Concept Renders view states Handles user interactions ViewController,Cell,...
  36. 36. Basic Concept protocol View { associatedtype Reactor var disposeBag: DisposeBag // gets called when // self.reactor is changed func bind(reactor: Reactor) }
  37. 37. Basic Concept protocol StoryboardView { associatedtype Reactor var disposeBag: DisposeBag // gets called when // the view is loaded func bind(reactor: Reactor) } // for Storyboard support
  38. 38. Basic Concept Performs business logic Manages states Corresponds to view
  39. 39. Basic Concept protocol Reactor { associatedtype Action associatedtype Mutation associatedtype State var initialState: State }
  40. 40. Basic Concept Based on RxSwift
  41. 41. Data Flow
  42. 42. Data Flow
  43. 43. Data Flow Action → State ❌
  44. 44. Data Flow Action → Mutation → State
  45. 45. Data Flow Action → Mutation → State State manipulator
  46. 46. Data Flow State manipulator Async-able Action → Mutation → State
  47. 47. Data Flow State manipulator Async-able Not exposed to view Action → Mutation → State
  48. 48. Data Flow (Action) -> Observable<Mutation> (State, Mutation) -> State
  49. 49. Data Flow
  50. 50. Data Flow class ProfileViewReactor: Reactor { enum Action { } struct State { } }
  51. 51. Data Flow class ProfileViewReactor: Reactor { enum Action { case follow // user interaction } struct State { } }
  52. 52. Data Flow class ProfileViewReactor: Reactor { enum Action { case follow // user interaction } struct State { var isFollowing: Bool // view state } }
  53. 53. Data Flow class ProfileViewReactor: Reactor { enum Action { case follow // user interaction } struct State { var isFollowing: Bool // view state } } Execute user follow API → Change state
  54. 54. Data Flow class ProfileViewReactor: Reactor { enum Action { case follow // user interaction } struct State { var isFollowing: Bool // view state } } Execute user follow API → Change state Async
  55. 55. Data Flow class ProfileViewReactor: Reactor { enum Action { case follow // user interaction } enum Mutation { } struct State { var isFollowing: Bool // view state } }
  56. 56. Data Flow class ProfileViewReactor: Reactor { enum Action { case follow // user interaction } enum Mutation { case setFollowing(Bool) // change state } struct State { var isFollowing: Bool // view state } }
  57. 57. Data Flow
  58. 58. Data Flow Tap follow button
  59. 59. Data Flow Action.follow
  60. 60. Data Flow Action.follow
  61. 61. Data Flow UserService.follow()
  62. 62. Data Flow UserService
  63. 63. Data Flow Observable<Bool>
  64. 64. Data Flow
  65. 65. Data Flow Mutation.setFollowing(true)
  66. 66. Data Flow Mutation.setFollowing(true)
  67. 67. Data Flow isFollowing = true
  68. 68. Data Flow Update follow button
  69. 69. Data Flow
  70. 70. More Examples
  71. 71. More Examples
  72. 72. Advanced View Communications Testing View and Reactor
  73. 73. View Communications ProfileViewController ProfileViewReactor
  74. 74. View Communications UICollectionView ProfileViewController ProfileViewReactor
  75. 75. View Communications UICollectionView ProfileViewController ProfileViewReactor UserCell
  76. 76. View Communications Passing user data Observing button tap
  77. 77. View Communications - Passing user data ProfileView Controller UserCell ProfileView Reactor
  78. 78. View Communications - Passing user data ProfileView Controller UserCell ProfileView Reactor 1.User
  79. 79. View Communications - Passing user data ProfileView Controller UserCell ProfileView Reactor 1.User 2.User
  80. 80. View Communications - Passing user data // ProfileViewReactor struct State { }
  81. 81. View Communications - Passing user data // ProfileViewReactor struct State { var user: User? }
  82. 82. View Communications - Passing user data // ProfileViewReactor struct State { var user: User? } // ProfileViewController let cell = collectionView.dequeue... return cell
  83. 83. View Communications - Passing user data // ProfileViewReactor struct State { var user: User? } // ProfileViewController let cell = collectionView.dequeue... if let reactor = self.reactor { } return cell
  84. 84. View Communications - Passing user data // ProfileViewReactor struct State { var user: User? } // ProfileViewController let cell = collectionView.dequeue... if let reactor = self.reactor { cell.user = reactor.currentState.user } return cell
  85. 85. View Communications - Observing button tap ProfileView Controller UserCell ProfileView Reactor
  86. 86. View Communications - Observing button tap ProfileView Controller UserCell ProfileView Reactor 1.rx.tap
  87. 87. View Communications - Observing button tap ProfileView Controller UserCell ProfileView Reactor 2.Action.follow 1.rx.tap
  88. 88. View Communications - Observing button tap ProfileView Controller UserCell ProfileView Reactor 2.Action.follow 1.rx.tap Reactive Extension
  89. 89. View Communications - Observing button tap // UserCell extension Reactive where Base: UserCell { }
  90. 90. View Communications - Observing button tap // UserCell extension Reactive where Base: UserCell { var buttonTap: ControlEvent<Void> { } }
  91. 91. View Communications - Observing button tap // UserCell extension Reactive where Base: UserCell { var buttonTap: ControlEvent<Void> { return self.base.followButton.rx.tap } }
  92. 92. View Communications - Observing button tap // UserCell extension Reactive where Base: UserCell { var buttonTap: ControlEvent<Void> { return self.base.followButton.rx.tap } } // ProfileViewController cell.user = reactor.currentState.user
  93. 93. View Communications - Observing button tap // UserCell extension Reactive where Base: UserCell { var buttonTap: ControlEvent<Void> { return self.base.followButton.rx.tap } } // ProfileViewController cell.user = reactor.currentState.user cell.rx.buttonTap
  94. 94. View Communications - Observing button tap // UserCell extension Reactive where Base: UserCell { var tap: ControlEvent<Void> { return self.base.followButton.rx.tap } } // ProfileViewController cell.user = reactor.currentState.user cell.rx.buttonTap .map { Reactor.Action.follow }
  95. 95. View Communications - Observing button tap // UserCell extension Reactive where Base: UserCell { var tap: ControlEvent<Void> { return self.base.followButton.rx.tap } } // ProfileViewController cell.user = reactor.currentState.user cell.rx.buttonTap .map { Reactor.Action.follow } .bind(to: reactor.action)
  96. 96. View Communications - Observing button tap // UserCell extension Reactive where Base: UserCell { var tap: ControlEvent<Void> { return self.base.followButton.rx.tap } } // ProfileViewController cell.user = reactor.currentState.user cell.rx.buttonTap .map { Reactor.Action.follow } .bind(to: reactor.action) .disposed(by: self.disposeBag)
  97. 97. View Communications UICollectionView ProfileViewController ProfileViewReactor UserCell
  98. 98. View Communications UICollectionView ProfileViewController ProfileViewReactor UserCell UserCellReactor
  99. 99. View Communications - Passing user data ProfileView Controller UserCell ProfileView Reactor
  100. 100. View Communications - Passing user data ProfileView Controller UserCell ProfileView Reactor UserCell Reactor
  101. 101. View Communications - Passing user data ProfileView Controller UserCell ProfileView Reactor 1.CellReactor UserCell Reactor
  102. 102. View Communications - Passing user data ProfileView Controller UserCell ProfileView Reactor 1.CellReactor 2.CellReactor UserCell Reactor
  103. 103. View Communications - Passing user data ProfileView Controller UserCell ProfileView Reactor 1.CellReactor 2.CellReactor UserCell Reactor
  104. 104. View Communications - Passing user data // ProfileViewReactor struct State { var user: User? }
  105. 105. View Communications - Passing user data // ProfileViewReactor struct State { var user: User? var userCellReactor: UserCellReactor? }
  106. 106. View Communications - Passing user data // ProfileViewReactor struct State { var user: User? var userCellReactor: UserCellReactor? } // ProfileViewController cell.user = reactor.currentState.user
  107. 107. View Communications - Passing user data // ProfileViewReactor struct State { var user: User? var userCellReactor: UserCellReactor? } // ProfileViewController cell.user = reactor.currentState.user cell.reactor = reactor.currentState.userCellReactor
  108. 108. Testing View and Reactor What to test? View Reactor
  109. 109. Testing View and Reactor What to test? View Action: on user interaction → action sent? Reactor
  110. 110. Testing View and Reactor What to test? View Action: on user interaction → action sent? State: on state change → view updated? Reactor
  111. 111. Testing View and Reactor What to test? View Action: on user interaction → action sent? State: on state change → view updated? Reactor State: on action receive → state updated?
  112. 112. Testing View and Reactor How to test?
  113. 113. Testing View and Reactor How to test? Reactor.stub()
  114. 114. Testing View and Reactor How to test? Reactor.stub() state: set fake state
  115. 115. Testing View and Reactor How to test? Reactor.stub() state: set fake state action: send fake action
  116. 116. Testing View and Reactor How to test? Reactor.stub() state: set fake state action: send fake action actions: log received actions
  117. 117. Testing View and Reactor - View Action
  118. 118. Testing View and Reactor - View Action When: follow button taps Then: sends follow action
  119. 119. Testing View and Reactor - View Action // given let reactor = ProfileViewReactor() // when // then
  120. 120. Testing View and Reactor - View Action // given let reactor = ProfileViewReactor() reactor.stub.isEnabled = true // when // then
  121. 121. Testing View and Reactor - View Action // given let reactor = ProfileViewReactor() reactor.stub.isEnabled = true reactor.stub.state.value.user = User() // when // then
  122. 122. Testing View and Reactor - View Action // given let reactor = ProfileViewReactor() reactor.stub.isEnabled = true reactor.stub.state.value.user = User() let viewController = ProfileViewController() viewController.reactor = reactor // when // then
  123. 123. Testing View and Reactor - View Action // given let reactor = ProfileViewReactor() reactor.stub.isEnabled = true reactor.stub.state.value.user = User() let viewController = ProfileViewController() viewController.reactor = reactor // when let button = viewController.userCell.followButton // then
  124. 124. Testing View and Reactor - View Action // given let reactor = ProfileViewReactor() reactor.stub.isEnabled = true reactor.stub.state.value.user = User() let viewController = ProfileViewController() viewController.reactor = reactor // when let button = viewController.userCell.followButton button.sendActions(for: .touchUpInside) // then
  125. 125. Testing View and Reactor - View Action // given let reactor = ProfileViewReactor() reactor.stub.isEnabled = true reactor.stub.state.value.user = User() let viewController = ProfileViewController() viewController.reactor = reactor // when let button = viewController.userCell.followButton button.sendActions(for: .touchUpInside) // then let lastAction = reactor.stub.actions.last XCTAssertEqual(lastAction, .follow)
  126. 126. Testing View and Reactor - View State When: following the user Then: button is selected
  127. 127. Testing View and Reactor - View State // given let cellReactor = UserCellReactor() // when // then
  128. 128. Testing View and Reactor - View State // given let cellReactor = UserCellReactor() cellReactor.stub.isEnabled = true // when // then
  129. 129. Testing View and Reactor - View State // given let cellReactor = UserCellReactor() cellReactor.stub.isEnabled = true let cell = UserCell() cell.reactor = cellReactor // when // then
  130. 130. Testing View and Reactor - View State // given let cellReactor = UserCellReactor() cellReactor.stub.isEnabled = true let cell = UserCell() cell.reactor = cellReactor // when cellReactor.stub.state.value.isFollowing = true // then
  131. 131. Testing View and Reactor - View State // given let cellReactor = UserCellReactor() cellReactor.stub.isEnabled = true let cell = UserCell() cell.reactor = cellReactor // when cellReactor.stub.state.value.isFollowing = true // then XCTAssertTrue(cell.followButton.isSelected)
  132. 132. Testing View and Reactor - Reactor State When: receive follow action Then: update following state ProfileView Reactor
  133. 133. Testing View and Reactor - Reactor State // given let reactor = ProfileViewReactor() // when // then
  134. 134. Testing View and Reactor - Reactor State // given let reactor = ProfileViewReactor() // when reactor.action.onNext(.follow) // then
  135. 135. Testing View and Reactor - Reactor State // given let reactor = ProfileViewReactor() // when reactor.action.onNext(.follow) // then let user = reactor.currentState.user XCTAssertEqual(user?.isFollowing, true)
  136. 136. Future Ideas Development Documentation Community
  137. 137. Development Testing Support SectionReactor AlertReactor ModelReactor Plugins ... Nested stub Dummy reactor ... Building Extensions
  138. 138. Documentation Best Practices Translations Code-level Documentation
  139. 139. Community RxSwift Slack #reactorkit (English) https://rxswift-slack.herokuapp.com Swift Korea Slack #reactorkit (Korean) http://slack.swiftkorea.org
  140. 140. https://reactorkit.io

×