connect라는 앱을 팀원과 함께 만들게되면서 MVVM 패턴을 도입하기로 하였고 이 중 ViewModel 파트를 RxSwift로 만들기로 하였으나 개발자마다 너무나 다른 스타일로 인해 각자 맡은 화면의 ViewModel코드가 많이 상이할까봐 나름 비슷한 구조로 만들고자 ReactorKit을 사용하기로 결정이 났다
처음 ReactorKit을 사용해보았는데 기본적인 사용방법과 내가 생각할때의 불편했던점을 기술해보고자 한다
class FruitReactor: Reactor {
// MARK: Actions
enum Action {
case apple
case banana
case grapes
}
// MARK: State
struct State {
var fruitName: String
var isLoading: Bool
}
//MARK: Mutations
enum Mutation { // Action이 Mutation으로 변경, 이 Mutation이 State로 생성될것임
case changeLabelApple
case changeLabelBanana
case changeLabelGrapes
case setLoading(Bool)
}
let initialState: State
init() {
self.initialState = State(fruitName: "선택되어진 과일없음", isLoading: false)
}
// MARK: Actions -> Mutation
func mutate(action: Action) -> Observable<Mutation> {
switch action {
case .apple:
return Observable.concat([
Observable.just(Mutation.setLoading(true)),
Observable.just(Mutation.changeLabelApple)
.delay(.milliseconds(500),
scheduler: MainScheduler.instance),
Observable.just(Mutation.setLoading(false))
])
case .banana:
return Observable.concat([
Observable.just(Mutation.setLoading(true)),
Observable.just(Mutation.changeLabelBanana)
.delay(.milliseconds(500),
scheduler: MainScheduler.instance),
Observable.just(Mutation.setLoading(false))
])
case .grapes:
return Observable.concat([
Observable.just(Mutation.setLoading(true)),
Observable.just(Mutation.changeLabelGrapes)
.delay(.milliseconds(500),
scheduler: MainScheduler.instance),
Observable.just(Mutation.setLoading(false))
])
}
}
// MARK: Mutation -> State
func reduce(state: State, mutation: Mutation) -> State {
var state = state
switch mutation {
case .changeLabelApple:
state.fruitName = "사과"
case .changeLabelBanana:
state.fruitName = "바나나"
case .changeLabelGrapes:
state.fruitName = "포도"
case .setLoading(let val):
state.isLoading = val
}
return state
}
}