diff --git a/MLS/Data/Data/Network/Endpoints/DictionaryListEndPoint.swift b/MLS/Data/Data/Network/Endpoints/DictionaryListEndPoint.swift index 1f31fedb..9de13a79 100644 --- a/MLS/Data/Data/Network/Endpoints/DictionaryListEndPoint.swift +++ b/MLS/Data/Data/Network/Endpoints/DictionaryListEndPoint.swift @@ -47,7 +47,7 @@ public enum DictionaryListEndPoint { let joinedCategoryIds = categoryIds?.map(String.init).joined(separator: ",") let joinedJobIds = jobId?.map(String.init).joined(separator: ",") - let query = DictionaryListQuery(keyword: keyword, page: page ?? 0, size: size ?? 20, sort: sort, minLevel: minLevel ?? 1, maxLevel: maxLevel ?? 200, jobIds: joinedJobIds, categoryIds: joinedCategoryIds) + let query = DictionaryListQuery(keyword: keyword, page: page ?? 0, size: size ?? 20, sort: sort, minLevel: minLevel, maxLevel: maxLevel, jobIds: joinedJobIds, categoryIds: joinedCategoryIds) return .init(baseURL: base, path: "/api/v1/items", method: .GET, query: query ) } diff --git a/MLS/Data/Data/Repository/UserDefaultsRepositoryImpl.swift b/MLS/Data/Data/Repository/UserDefaultsRepositoryImpl.swift index 991699f3..55a01487 100644 --- a/MLS/Data/Data/Repository/UserDefaultsRepositoryImpl.swift +++ b/MLS/Data/Data/Repository/UserDefaultsRepositoryImpl.swift @@ -50,6 +50,21 @@ public final class UserDefaultsRepositoryImpl: UserDefaultsRepository { } } + public func removeAllSearch() -> Completable { + return Completable.create { completable in + var current = UserDefaults.standard.stringArray(forKey: self.recentSearchkey) ?? [] + + // 해당 키워드 제거 + current.removeAll() + + // 다시 저장 + UserDefaults.standard.set(current, forKey: self.recentSearchkey) + + completable(.completed) + return Disposables.create() + } + } + public func fetchPlatform() -> Observable { return Observable.create { observer in if let rawValue = UserDefaults.standard.string(forKey: self.platformKey), diff --git a/MLS/Domain/Domain/UseCaseImpl/RecentSearch/RecentSearchRemoveUseCaseImpl.swift b/MLS/Domain/Domain/UseCaseImpl/RecentSearch/RecentSearchRemoveUseCaseImpl.swift index 9fdb545c..f130bd25 100644 --- a/MLS/Domain/Domain/UseCaseImpl/RecentSearch/RecentSearchRemoveUseCaseImpl.swift +++ b/MLS/Domain/Domain/UseCaseImpl/RecentSearch/RecentSearchRemoveUseCaseImpl.swift @@ -5,6 +5,7 @@ import RxSwift public class RecentSearchRemoveUseCaseImpl: RecentSearchRemoveUseCase { var repository: UserDefaultsRepository + public init(repository: UserDefaultsRepository) { self.repository = repository } @@ -12,4 +13,8 @@ public class RecentSearchRemoveUseCaseImpl: RecentSearchRemoveUseCase { public func remove(keyword: String) -> Completable { return repository.removeRecentSearch(keyword: keyword) } + + public func removeAll() -> Completable { + return repository.removeAllSearch() + } } diff --git a/MLS/Domain/DomainInterface/Repository/UserDefaultsRepository.swift b/MLS/Domain/DomainInterface/Repository/UserDefaultsRepository.swift index 763c10d2..f837248e 100644 --- a/MLS/Domain/DomainInterface/Repository/UserDefaultsRepository.swift +++ b/MLS/Domain/DomainInterface/Repository/UserDefaultsRepository.swift @@ -4,6 +4,7 @@ public protocol UserDefaultsRepository { func fetchRecentSearch() -> Observable<[String]> func addRecentSearch(keyword: String) -> Completable func removeRecentSearch(keyword: String) -> Completable + func removeAllSearch() -> Completable func fetchPlatform() -> Observable func savePlatform(platform: LoginPlatform) -> Completable diff --git a/MLS/Domain/DomainInterface/UseCase/RecentSearch/RecentSearchRemoveUseCase.swift b/MLS/Domain/DomainInterface/UseCase/RecentSearch/RecentSearchRemoveUseCase.swift index 19a89a8f..5a6e9792 100644 --- a/MLS/Domain/DomainInterface/UseCase/RecentSearch/RecentSearchRemoveUseCase.swift +++ b/MLS/Domain/DomainInterface/UseCase/RecentSearch/RecentSearchRemoveUseCase.swift @@ -2,4 +2,5 @@ import RxSwift public protocol RecentSearchRemoveUseCase { func remove(keyword: String) -> Completable + func removeAll() -> Completable } diff --git a/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/CollectionViewCells/DictionaryNotificationCell.swift b/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/CollectionViewCells/DictionaryNotificationCell.swift index 478d83d0..db03aa1d 100644 --- a/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/CollectionViewCells/DictionaryNotificationCell.swift +++ b/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/CollectionViewCells/DictionaryNotificationCell.swift @@ -84,6 +84,6 @@ public extension DictionaryNotificationCell { subTitleLabel.attributedText = .makeStyledString(font: .b_s_r, text: input.subTitle, color: input.isChecked ? .neutral500 : .neutral700, alignment: .left) backgroundColor = input.isChecked ? .neutral100 : .clearMLS layer.cornerRadius = input.isChecked ? Constant.radius : 0 - checkIcon.isHidden = !input.isChecked + checkIcon.isHidden = input.isChecked } } diff --git a/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/Views/RecentSearchHeaderView.swift b/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/Views/RecentSearchHeaderView.swift index cfb1606a..878213a8 100644 --- a/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/Views/RecentSearchHeaderView.swift +++ b/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/Views/RecentSearchHeaderView.swift @@ -5,7 +5,7 @@ import UIKit public final class RecentSearchHeaderView: UICollectionReusableView { // MARK: - Components private let titleLabel = UILabel() - private let deleteButton = UIButton() + public let deleteButton = UIButton() private let spacer = UIView() // MARK: - Init diff --git a/MLS/Presentation/BookmarkFeature/BookmarkFeature/BookmarkList/BookmarkListViewController.swift b/MLS/Presentation/BookmarkFeature/BookmarkFeature/BookmarkList/BookmarkListViewController.swift index 5f7e9777..853d175a 100644 --- a/MLS/Presentation/BookmarkFeature/BookmarkFeature/BookmarkList/BookmarkListViewController.swift +++ b/MLS/Presentation/BookmarkFeature/BookmarkFeature/BookmarkList/BookmarkListViewController.swift @@ -339,7 +339,7 @@ extension BookmarkListViewController: UICollectionViewDelegate, UICollectionView onBookmarkTapped: { [weak self] in guard let self else { return } - guard state.isLogin else { + guard self.reactor?.currentState.isLogin == true else { self.reactor?.action.onNext(.showLogin) return } diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseViewController.swift index 4245a583..84d5dfcb 100644 --- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseViewController.swift +++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseViewController.swift @@ -22,9 +22,9 @@ class DictionaryDetailBaseViewController: BaseViewController { /// 각 탭에 해당하는 콘텐츠 뷰들을 담는 배열 public var contentViews: [UIView] = [] { didSet { - if let index = currentTabIndex { - mainView.setTabView(index: index, contentViews: contentViews) - } + let index = currentTabIndex ?? 0 + guard index < contentViews.count else { return } + mainView.setTabView(index: index, contentViews: contentViews) } } diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListViewController.swift index 6f22ceef..c89a9695 100644 --- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListViewController.swift +++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListViewController.swift @@ -372,7 +372,7 @@ extension DictionaryListViewController: UICollectionViewDelegate, UICollectionVi isMap: item.type == .map, onBookmarkTapped: { [weak self] in guard let self else { return } - guard state.isLogin else { + guard self.reactor?.currentState.isLogin == true else { self.reactor?.action.onNext(.showLogin) return } diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchReactor.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchReactor.swift index cb2819dd..98e3b950 100644 --- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchReactor.swift +++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchReactor.swift @@ -20,12 +20,14 @@ public final class DictionarySearchReactor: Reactor { case backButtonTapped case searchButtonTapped(String) case cancelRecentButtonTapped(String) + case deleteAllButtonTapped case recentButtonTapped(String) } public enum Mutation { case navigateTo(Route) case deleteItem(String) + case deleteAllItems case addRecentItem(String) case setRecentList([String]) } @@ -106,6 +108,9 @@ public final class DictionarySearchReactor: Reactor { .andThen(.just(.deleteItem(keyword))) case .recentButtonTapped(let keyword): return Observable.just(.navigateTo(.search(keyword))) + case .deleteAllButtonTapped: + return recentSearchRemoveUseCase.removeAll() + .andThen(.just(.deleteAllItems)) } } @@ -121,6 +126,8 @@ public final class DictionarySearchReactor: Reactor { newState.recentResult.insert(name, at: 0) // 맨 앞에 최근 검색어 추가 case .deleteItem(let name): newState.recentResult = state.recentResult.filter { $0 != name } + case .deleteAllItems: + newState.recentResult = [] } return newState diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchViewController.swift index a1b2dede..9d826ca9 100644 --- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchViewController.swift +++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchViewController.swift @@ -242,11 +242,19 @@ extension DictionarySearchViewController: UICollectionViewDelegate, UICollection ) -> UICollectionReusableView { switch indexPath.section { case 0: - let view = collectionView.dequeueReusableSupplementaryView( + guard let view = collectionView.dequeueReusableSupplementaryView( ofKind: kind, withReuseIdentifier: RecentSearchHeaderView.identifier, for: indexPath - ) as! RecentSearchHeaderView + ) as? RecentSearchHeaderView else { return UICollectionViewCell() } + + guard let reactor = reactor else { return UICollectionViewCell() } + + view.deleteButton.rx.tap + .map { Reactor.Action.deleteAllButtonTapped } + .bind(to: reactor.action) + .disposed(by: disposeBag) + return view case 2: