diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index b48334f7..3f4fc566 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -131,6 +131,7 @@ DA20D847296697A600F1581F /* MyCourseSelectVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA20D846296697A600F1581F /* MyCourseSelectVC.swift */; }; DA20D849296697B400F1581F /* CourseUploadVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA20D848296697B400F1581F /* CourseUploadVC.swift */; }; DA20D84E2966A9B300F1581F /* CourseSearchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA20D84D2966A9B300F1581F /* CourseSearchVC.swift */; }; + DA97A02F296DC3300086760E /* CourseSearchingRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA97A02E296DC3300086760E /* CourseSearchingRouter.swift */; }; DAD5A3D8296C6D9600C8166B /* AdImageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAD5A3D7296C6D9600C8166B /* AdImageCollectionViewCell.swift */; }; DAD5A3DA296C6DA500C8166B /* TitleCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAD5A3D9296C6DA500C8166B /* TitleCollectionViewCell.swift */; }; DAD5A3DC296C6DB800C8166B /* MapCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAD5A3DB296C6DB800C8166B /* MapCollectionViewCell.swift */; }; @@ -282,6 +283,7 @@ DA20D846296697A600F1581F /* MyCourseSelectVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCourseSelectVC.swift; sourceTree = ""; }; DA20D848296697B400F1581F /* CourseUploadVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseUploadVC.swift; sourceTree = ""; }; DA20D84D2966A9B300F1581F /* CourseSearchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseSearchVC.swift; sourceTree = ""; }; + DA97A02E296DC3300086760E /* CourseSearchingRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseSearchingRouter.swift; sourceTree = ""; }; DAD5A3D7296C6D9600C8166B /* AdImageCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdImageCollectionViewCell.swift; sourceTree = ""; }; DAD5A3D9296C6DA500C8166B /* TitleCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleCollectionViewCell.swift; sourceTree = ""; }; DAD5A3DB296C6DB800C8166B /* MapCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapCollectionViewCell.swift; sourceTree = ""; }; @@ -414,6 +416,7 @@ CE10063529680C0F00FD31FB /* CourseDiscoveryDto */ = { isa = PBXGroup; children = ( + DA97A029296DC2020086760E /* RequestDto */, DAD5A3E0296D4C2A00C8166B /* ResponseDto */, ); path = CourseDiscoveryDto; @@ -730,6 +733,7 @@ isa = PBXGroup; children = ( DAD5A3E3296D526D00C8166B /* CourseDiscoveryRouter.swift */, + DA97A02E296DC3300086760E /* CourseSearchingRouter.swift */, ); path = CourseDiscoveryRouter; sourceTree = ""; @@ -1129,6 +1133,13 @@ path = VC; sourceTree = ""; }; + DA97A029296DC2020086760E /* RequestDto */ = { + isa = PBXGroup; + children = ( + ); + path = RequestDto; + sourceTree = ""; + }; DAD5A3E0296D4C2A00C8166B /* ResponseDto */ = { isa = PBXGroup; children = ( @@ -1312,6 +1323,7 @@ DAD5A3E4296D526D00C8166B /* CourseDiscoveryRouter.swift in Sources */, CEEC6B3E2961C53700D00E1E /* CourseDiscoveryVC.swift in Sources */, CE6655E0295D87D200C64E12 /* UIDevice+.swift in Sources */, + DA97A02F296DC3300086760E /* CourseSearchingRouter.swift in Sources */, CE40BB242968068E0030ABCA /* Config.swift in Sources */, CE17F0382961BF8B00E1DED0 /* FontLiterals.swift in Sources */, CE6655E8295D889600C64E12 /* UISwitch+.swift in Sources */, diff --git a/Runnect-iOS/Runnect-iOS/Network/Router/CourseDiscoveryRouter/CourseDiscoveryRouter.swift b/Runnect-iOS/Runnect-iOS/Network/Router/CourseDiscoveryRouter/CourseDiscoveryRouter.swift index 8d09ed2d..7992ab49 100644 --- a/Runnect-iOS/Runnect-iOS/Network/Router/CourseDiscoveryRouter/CourseDiscoveryRouter.swift +++ b/Runnect-iOS/Runnect-iOS/Network/Router/CourseDiscoveryRouter/CourseDiscoveryRouter.swift @@ -18,7 +18,6 @@ extension pickedMapListRouter: TargetType { guard let url = URL(string: Config.baseURL) else { fatalError("baseURL could not be configured") } - return url } diff --git a/Runnect-iOS/Runnect-iOS/Network/Router/CourseDiscoveryRouter/CourseSearchingRouter.swift b/Runnect-iOS/Runnect-iOS/Network/Router/CourseDiscoveryRouter/CourseSearchingRouter.swift new file mode 100644 index 00000000..da06fafa --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Network/Router/CourseDiscoveryRouter/CourseSearchingRouter.swift @@ -0,0 +1,51 @@ +// +// CourseSearchingRouter.swift +// Runnect-iOS +// +// Created by YEONOO on 2023/01/11. +// + +import Foundation + +import Moya + +enum CourseSearchingRouter { + case getCourseData(keyword: String) +} + +extension CourseSearchingRouter: TargetType { + var baseURL: URL { + guard let url = URL(string: Config.baseURL) else { + fatalError("baseURL could not be configured") + } + return url + } + + var path: String { + switch self { + case .getCourseData: + return "/public-course/search" + } + } + + var method: Moya.Method { + switch self { + case .getCourseData: + return .get + } + } + + var task: Moya.Task { + switch self { + case .getCourseData(let keyword): + return .requestParameters(parameters: ["keyword": keyword], encoding: URLEncoding.default) + } + } + + var headers: [String: String]? { + switch self { + case .getCourseData: + return Config.headerWithDeviceId + } + } +} diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDiscovery/Views/VC/CourseSearchVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDiscovery/Views/VC/CourseSearchVC.swift index d7879563..96e0dc3c 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDiscovery/Views/VC/CourseSearchVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDiscovery/Views/VC/CourseSearchVC.swift @@ -9,9 +9,17 @@ import UIKit import Then import SnapKit +import Moya final class CourseSearchVC: UIViewController { + // MARK: - Properties + + private let CourseSearchingRouter = MoyaProvider( + plugins: [NetworkLoggerPlugin(verbose: true)]) + + private var courseList = [PublicCourse]() + // MARK: - UI Components private lazy var naviBar = CustomNavigationBar(self, type: .search).setTextFieldPlaceholder(placeholder: "지역과 키워드 위주로 검색해보세요").showKeyboard() @@ -62,7 +70,7 @@ final class CourseSearchVC: UIViewController { setDelegate() layout() setTabBar() - + } } // MARK: - Methods @@ -70,6 +78,7 @@ final class CourseSearchVC: UIViewController { extension CourseSearchVC { private func setDelegate() { + self.naviBar.delegate = self self.mapCollectionView.delegate = self self.mapCollectionView.dataSource = self } @@ -79,7 +88,11 @@ extension CourseSearchVC { } private func setTabBar() { - self.tabBarController?.tabBar.isHidden = true + self.tabBarController?.tabBar.isHidden = true + } + private func setData(data: [PublicCourse]) { + self.courseList = data + mapCollectionView.reloadData() } } @@ -116,14 +129,17 @@ extension CourseSearchVC { extension CourseSearchVC: UICollectionViewDelegate, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return 15 - } - + return courseList.count + } + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CourseListCVC.className, for: indexPath) as? CourseListCVC else { return UICollectionViewCell() } cell.setCellType(type: .all) + let model = self.courseList[indexPath.item] + let location = "\(model.departure.region) \(model.departure.city)" + cell.setData(imageURL: model.image, title: model.title, location: location, didLike: model.scarp) return cell } } @@ -153,3 +169,40 @@ extension CourseSearchVC: UICollectionViewDelegateFlowLayout { self.naviBar.hideKeyboard() } } +// MARK: - CustomNavigationBarDelegate + +extension CourseSearchVC: CustomNavigationBarDelegate { + func searchButtonDidTap(text: String) { + searchCourseWithKeyword(keyword: text) + } +} +// MARK: - Network + +extension CourseSearchVC { + private func searchCourseWithKeyword(keyword: String) { + LoadingIndicator.showLoading() + CourseSearchingRouter.request(.getCourseData(keyword: keyword)) { response in + LoadingIndicator.hideLoading() + switch response { + case .success(let result): + let status = result.statusCode + if 200..<300 ~= status { + do { + let responseDto = try result.map(BaseResponse.self) + guard let data = responseDto.data else { return } + self.setData(data: data.publicCourses) + } catch { + print(error.localizedDescription) + } + } + if status >= 400 { + print("400 error") + self.showNetworkFailureToast() + } + case .failure(let error): + print(error.localizedDescription) + self.showNetworkFailureToast() + } + } + } +}