-
Notifications
You must be signed in to change notification settings - Fork 0
[REFACTOR] 검색 화면 모듈화 #146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[REFACTOR] 검색 화면 모듈화 #146
Changes from 139 commits
8db3f9a
55e2f41
52dce12
caa5893
38fa728
94f4188
cbb41a0
a23bbf7
7d3ca88
e4a8652
62d35a6
f731e4f
519b187
6abccbf
9330680
b3fbe66
e11325b
f0c651f
e6f3f0e
6dfe683
be5d716
a9adab4
2a056b3
8929ecf
24bfa12
150585d
d485a11
373f616
1d90d08
c185aef
03cf353
cd9c91f
6f8adc7
bd9310e
ffc349f
058046c
7a2b465
85752c8
3b698fe
d9a51d2
2519e09
2eae6f1
10641e7
24ff9bb
f0599ac
94c8618
89a0627
4e001e5
d37cd92
1d0005c
61a77c1
fac0c99
284b024
b253af9
3f3d657
f49470f
c7e566b
e83fa26
219e951
9a02893
77c4291
aedac21
9b56f1d
d722253
b206651
a30e02b
25c1912
6b457d2
04fd431
bc3e11b
03565ed
34c79e5
32abac6
3110b6b
fa5ca67
0000bee
30d89c0
0e7a532
63c427d
2d2901a
7dd1de6
6a836b6
d9ea5b7
22225f6
46217e4
1ed5563
648af9b
081bccf
1d8aaa3
1984486
2d7e31d
2b5f0af
2d981ba
e4991ab
11ac459
8b6993b
c220a7d
4ad4acc
99652b6
4530ec9
4fb4617
7eea641
743f3ec
e44ca64
64cf9e4
538431f
79424c0
f436601
d8a8676
069bbfd
74b42eb
f6c8757
5783777
c58af06
2fd0421
4662ada
559e17f
f83725a
de168f8
87517f3
107ea1b
2af8b16
c19b503
4143682
8c231c9
a51fda6
3521057
360a858
9aca3d2
c505cd5
69b2944
12f2e66
0eec33b
43e5f2b
5f93b5e
a6070ae
1e6c28f
bb997f6
2003292
4382cf1
f6ecadb
edaa734
b4f5e85
429c3a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import Foundation | ||
|
|
||
| import Infrastructure | ||
|
|
||
| struct CategoryAPIEndpoint { | ||
|
|
||
| /// 관심사 목록을 가져옵니다. | ||
| /// - Returns: Endpoint<GetInterestListResponseDTO> | ||
| static func getCategoryList() -> Endpoint<GetCategoryListResponseDTO> { | ||
| return Endpoint( | ||
| baseURL: Secrets.popPoolBaseURL, | ||
| path: "/categories", | ||
| method: .get | ||
| ) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| import Foundation | ||
|
|
||
| struct GetSearchPopupStoreRequestDTO: Encodable { | ||
| let query: String | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import Foundation | ||
|
|
||
| import DomainInterface | ||
|
|
||
| struct GetSearchPopupStoreResponseDTO: Decodable { | ||
| var popUpStoreList: [PopUpStoreResponseDTO] | ||
| var loginYn: Bool | ||
| } | ||
|
|
||
| extension GetSearchPopupStoreResponseDTO { | ||
| func toDomain() -> KeywordBasePopupStoreListResponse { | ||
| return KeywordBasePopupStoreListResponse( | ||
| popupStoreList: popUpStoreList.map { $0.toDomain() }, | ||
| loginYn: loginYn | ||
| ) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import Foundation | ||
|
|
||
| import Infrastructure | ||
|
|
||
| import RxSwift | ||
|
|
||
| struct SearchAPIEndPoint { | ||
|
|
||
| static func getSearchPopUpList(request: GetSearchPopupStoreRequestDTO) -> Endpoint<GetSearchPopupStoreResponseDTO> { | ||
| return Endpoint( | ||
| baseURL: Secrets.popPoolBaseURL, | ||
| path: "/search/popup-stores", | ||
| method: .get, | ||
| queryParameters: request | ||
| ) | ||
| } | ||
| } |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저희가 사용하는 프로퍼티의 타입이 Int로 수정된 부분 확인하였습니다! |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import Foundation | ||
|
|
||
| import DomainInterface | ||
|
|
||
| import RxSwift | ||
|
|
||
| public final class CategoryRepositoryImpl: CategoryRepository { | ||
|
|
||
| private let provider: Provider | ||
|
|
||
| public init(provider: Provider) { | ||
| self.provider = provider | ||
| } | ||
|
|
||
| public func fetchCategoryList() -> Observable<[CategoryResponse]> { | ||
| let endPoint = CategoryAPIEndpoint.getCategoryList() | ||
| return provider.requestData(with: endPoint, interceptor: TokenInterceptor()).map { responseDTO in | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tokenInterceptor를 class에서 생성하지 않고 사용할 때 마다 사용하는 이유가 궁금한데 이유를 알 수 있을까요?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 의존성 주입 개념으로 넣어두었고, 추후 인터페이스 추상화를 통해 주입해주면 좋겠다 싶어 우선적으로 저렇게 뒀었습니다 |
||
| return responseDTO.categoryResponseList.map({ $0.toDomain() }) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import Foundation | ||
|
|
||
| import DomainInterface | ||
| import Infrastructure | ||
|
|
||
| import RxSwift | ||
|
|
||
| public final class SearchAPIRepositoryImpl: SearchAPIRepository { | ||
|
|
||
| private let provider: Provider | ||
| private let tokenInterceptor = TokenInterceptor() | ||
| private let userDefaultService: UserDefaultService | ||
|
|
||
| public init( | ||
| provider: Provider, | ||
| userDefaultService: UserDefaultService | ||
| ) { | ||
| self.provider = provider | ||
| self.userDefaultService = userDefaultService | ||
| } | ||
|
|
||
| public func fetchSearchResult(by query: String) -> Observable<KeywordBasePopupStoreListResponse> { | ||
|
|
||
| let request = GetSearchPopupStoreRequestDTO(query: query) | ||
| let endPoint = SearchAPIEndPoint.getSearchPopUpList(request: request) | ||
| return provider.requestData( // 실패했을때는 키워드 저장이 안되도록 수정 | ||
|
||
| with: endPoint, | ||
| interceptor: tokenInterceptor | ||
| ) | ||
| .map { $0.toDomain() } | ||
| .do { _ in self.saveSearchKeyword(keyword: query) } | ||
| } | ||
| } | ||
|
|
||
| private extension SearchAPIRepositoryImpl { | ||
| func saveSearchKeyword(keyword: String) { | ||
| let existingList = userDefaultService.fetchArray(keyType: .searchKeyword) ?? [] | ||
| let updatedList = [keyword] + existingList.filter { $0 != keyword } | ||
| userDefaultService.save(keyType: .searchKeyword, value: updatedList) | ||
| } | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 개별 UseCase -> excute 의 형태!! 확인하였습니다 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import Foundation | ||
|
|
||
| import DomainInterface | ||
|
|
||
| import RxSwift | ||
|
|
||
| public final class FetchCategoryListUseCaseImpl: FetchCategoryListUseCase { | ||
|
|
||
| private let repository: CategoryRepository | ||
|
|
||
| public init(repository: CategoryRepository) { | ||
| self.repository = repository | ||
| } | ||
|
|
||
| public func execute() -> Observable<[CategoryResponse]> { | ||
| return repository.fetchCategoryList() | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UserDefaultService를 key별로 사용할 수 있군요!!