Skip to content

Commit b8d06ab

Browse files
authored
Merge pull request #378 from Team-return/feature/(#377)-Company_ReactorKit_Refactoring
🔗 :: (#377) Company ReactorKit Refactoring
2 parents e736851 + f7542e0 commit b8d06ab

File tree

7 files changed

+163
-112
lines changed

7 files changed

+163
-112
lines changed

Projects/Flow/Sources/Company/CompanyFlow.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private extension CompanyFlow {
3434
func navigateToCompany() -> FlowContributors {
3535
return .one(flowContributor: .contribute(
3636
withNextPresentable: rootViewController,
37-
withNextStepper: rootViewController.viewModel
37+
withNextStepper: rootViewController.reactor
3838
))
3939
}
4040

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import ReactorKit
2+
import RxSwift
3+
import RxCocoa
4+
import RxFlow
5+
import Core
6+
import Domain
7+
8+
public final class CompanyReactor: BaseReactor, Stepper {
9+
public let steps = PublishRelay<Step>()
10+
public let initialState: State
11+
private let fetchCompanyListUseCase: FetchCompanyListUseCase
12+
13+
public init(
14+
fetchCompanyListUseCase: FetchCompanyListUseCase
15+
) {
16+
self.initialState = .init()
17+
self.fetchCompanyListUseCase = fetchCompanyListUseCase
18+
}
19+
20+
public enum Action {
21+
case fetchCompanyList
22+
case loadMoreCompanies
23+
case companyDidSelect(Int)
24+
case searchButtonDidTap
25+
}
26+
27+
public enum Mutation {
28+
case setCompanyList([CompanyEntity])
29+
case appendCompanyList([CompanyEntity])
30+
case incrementPageCount
31+
case resetPageCount
32+
}
33+
34+
public struct State {
35+
var companyList: [CompanyEntity] = []
36+
var pageCount: Int = 1
37+
}
38+
}
39+
40+
extension CompanyReactor {
41+
public func mutate(action: Action) -> Observable<Mutation> {
42+
switch action {
43+
case .fetchCompanyList:
44+
return .concat([
45+
.just(.resetPageCount),
46+
fetchCompanyListUseCase.execute(page: 1)
47+
.asObservable()
48+
.flatMap { list -> Observable<Mutation> in
49+
return .just(.setCompanyList(list))
50+
}
51+
])
52+
53+
case .loadMoreCompanies:
54+
let nextPage = currentState.pageCount + 1
55+
return fetchCompanyListUseCase.execute(page: nextPage)
56+
.asObservable()
57+
.catch { _ in .empty() }
58+
.filter { !$0.isEmpty }
59+
.flatMap { list -> Observable<Mutation> in
60+
return .concat([
61+
.just(.appendCompanyList(list)),
62+
.just(.incrementPageCount)
63+
])
64+
}
65+
66+
case let .companyDidSelect(id):
67+
steps.accept(CompanyStep.companyDetailIsRequired(id: id))
68+
return .empty()
69+
70+
case .searchButtonDidTap:
71+
steps.accept(CompanyStep.searchCompanyIsRequired)
72+
return .empty()
73+
}
74+
}
75+
76+
public func reduce(state: State, mutation: Mutation) -> State {
77+
var newState = state
78+
switch mutation {
79+
case let .setCompanyList(list):
80+
newState.companyList = list
81+
82+
case let .appendCompanyList(list):
83+
newState.companyList.append(contentsOf: list)
84+
85+
case .incrementPageCount:
86+
newState.pageCount += 1
87+
88+
case .resetPageCount:
89+
newState.pageCount = 1
90+
}
91+
return newState
92+
}
93+
}

Projects/Presentation/Sources/Company/CompanyViewController.swift

Lines changed: 66 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ import Then
77
import Core
88
import DesignSystem
99

10-
public final class CompanyViewController: BaseViewController<CompanyViewModel> {
11-
private var viewWillAppearWithTap: (() -> Void)?
12-
private var isTabNavigation: Bool = true
13-
private let searchButtonDidTap = PublishRelay<Void>()
10+
public final class CompanyViewController: BaseReactorViewController<CompanyReactor> {
11+
public var viewWillAppearWithTap: (() -> Void)?
12+
public var isTabNavigation: Bool = true
1413
private let companyTableView = UITableView().then {
1514
$0.register(
1615
CompanyTableViewCell.self,
@@ -36,38 +35,55 @@ public final class CompanyViewController: BaseViewController<CompanyViewModel> {
3635
}
3736
}
3837

39-
public override func bind() {
40-
let input = CompanyViewModel.Input(
41-
viewAppear: self.viewDidLoadPublisher,
42-
pageChange: companyTableView.rx.willDisplayCell
43-
.filter {
44-
$0.indexPath.row == self.companyTableView.numberOfRows(
45-
inSection: $0.indexPath.section
46-
) - 1
47-
},
48-
companyTableViewCellDidTap: companyTableView.rx.modelSelected(CompanyEntity.self)
49-
.map { $0.companyID }
50-
.do(onNext: { _ in
51-
self.isTabNavigation = false
52-
}),
53-
searchButtonDidTap: searchButtonDidTap
54-
)
38+
public override func bindAction() {
39+
viewDidLoadPublisher
40+
.map { CompanyReactor.Action.fetchCompanyList }
41+
.bind(to: reactor.action)
42+
.disposed(by: disposeBag)
5543

56-
let output = viewModel.transform(input)
44+
companyTableView.rx.willDisplayCell
45+
.filter {
46+
$0.indexPath.row == self.companyTableView.numberOfRows(
47+
inSection: $0.indexPath.section
48+
) - 1
49+
}
50+
.map { _ in CompanyReactor.Action.loadMoreCompanies }
51+
.bind(to: reactor.action)
52+
.disposed(by: disposeBag)
5753

58-
output.companyList
59-
.skip(1)
60-
.bind(
61-
to: companyTableView.rx.items(
62-
cellIdentifier: CompanyTableViewCell.identifier,
63-
cellType: CompanyTableViewCell.self
64-
)) { _, element, cell in
65-
cell.adapt(model: element)
54+
companyTableView.rx.itemSelected
55+
.do(onNext: { _ in
56+
self.isTabNavigation = false
57+
})
58+
.compactMap { [weak self] indexPath -> Int? in
59+
guard let self = self,
60+
indexPath.row < self.reactor.currentState.companyList.count else {
61+
return nil
6662
}
67-
.disposed(by: disposeBag)
63+
return self.reactor.currentState.companyList[indexPath.row].companyID
64+
}
65+
.map { CompanyReactor.Action.companyDidSelect($0) }
66+
.bind(to: reactor.action)
67+
.disposed(by: disposeBag)
68+
69+
searchButton.rx.tap
70+
.map { CompanyReactor.Action.searchButtonDidTap }
71+
.bind(to: reactor.action)
72+
.disposed(by: disposeBag)
73+
}
74+
75+
public override func bindState() {
76+
reactor.state.map { $0.companyList }
77+
.skip(1)
78+
.bind(onNext: { [weak self] _ in
79+
self?.companyTableView.reloadData()
80+
})
81+
.disposed(by: disposeBag)
6882
}
6983

7084
public override func configureViewController() {
85+
companyTableView.dataSource = self
86+
7187
viewWillAppearPublisher.asObservable()
7288
.bind {
7389
self.hideTabbar()
@@ -78,12 +94,6 @@ public final class CompanyViewController: BaseViewController<CompanyViewModel> {
7894
self.isTabNavigation = true
7995
}
8096
.disposed(by: disposeBag)
81-
82-
searchButton.rx.tap
83-
.subscribe(onNext: { _ in
84-
self.searchButtonDidTap.accept(())
85-
})
86-
.disposed(by: disposeBag)
8797
}
8898

8999
public override func configureNavigation() {
@@ -93,3 +103,23 @@ public final class CompanyViewController: BaseViewController<CompanyViewModel> {
93103
]
94104
}
95105
}
106+
107+
extension CompanyViewController: UITableViewDataSource {
108+
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
109+
return reactor.currentState.companyList.count
110+
}
111+
112+
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
113+
guard let cell = tableView.dequeueReusableCell(
114+
withIdentifier: CompanyTableViewCell.identifier,
115+
for: indexPath
116+
) as? CompanyTableViewCell else {
117+
return UITableViewCell()
118+
}
119+
120+
let company = reactor.currentState.companyList[indexPath.row]
121+
cell.adapt(model: company)
122+
123+
return cell
124+
}
125+
}

Projects/Presentation/Sources/Company/CompanyViewModel.swift

Lines changed: 0 additions & 70 deletions
This file was deleted.

Projects/Presentation/Sources/DI/Assembly/MainPresentationAssembly.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,11 @@ public final class MainPresentationAssembly: Assembly {
144144
// Company
145145
container.register(CompanyViewController.self) { resolver in
146146
CompanyViewController(
147-
resolver.resolve(CompanyViewModel.self)!
147+
resolver.resolve(CompanyReactor.self)!
148148
)
149149
}
150-
container.register(CompanyViewModel.self) { resolver in
151-
CompanyViewModel(fetchCompanyListUseCase: resolver.resolve(FetchCompanyListUseCase.self)!)
150+
container.register(CompanyReactor.self) { resolver in
151+
CompanyReactor(fetchCompanyListUseCase: resolver.resolve(FetchCompanyListUseCase.self)!)
152152
}
153153

154154
// Company Detail

Projects/Presentation/Sources/MyPage/MyPageReactor.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ public final class MyPageReactor: BaseReactor, Stepper {
4040

4141
public var initialState: State
4242
public let steps = PublishRelay<Step>()
43-
private let disposeBag = DisposeBag()
4443

4544
private let fetchPresignedURLUseCase: FetchPresignedURLUseCase
4645
private let uploadImageToS3UseCase: UploadImageToS3UseCase

Projects/Presentation/Sources/Recruitment/RecruitmentReactor.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import Domain
88
public final class RecruitmentReactor: BaseReactor, Stepper {
99
public let steps = PublishRelay<Step>()
1010
public let initialState: State
11-
private let disposeBag = DisposeBag()
1211
private let fetchRecruitmentListUseCase: FetchRecruitmentListUseCase
1312
private let bookmarkUseCase: BookmarkUseCase
1413

0 commit comments

Comments
 (0)