From 8f54c5ee6985e9d5a54ba9dab2c5e21ea1bdae38 Mon Sep 17 00:00:00 2001 From: jeongdung-eo Date: Fri, 13 Jan 2023 23:20:09 +0900 Subject: [PATCH] =?UTF-8?q?[FEAT]=20#84=20-=20=EC=84=B1=EC=B7=A8=EB=B7=B0?= =?UTF-8?q?=20=EC=9B=94=EA=B0=84=20=EC=BA=98=EB=A6=B0=EB=8D=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NotToDo/NotToDo.xcodeproj/project.pbxproj | 8 +++ NotToDo/NotToDo/Global/Extensions/Date+.swift | 17 ++++++ .../NotToDo/Global/Extensions/String+.swift | 23 +++++++ .../Achieve/AchieveCalendarResponseDTO.swift | 16 +++++ .../AchievementViewController.swift | 61 ++++++++----------- .../Views/CustomCalendarView.swift | 2 +- .../Views/MissionStatisticsView.swift | 1 - .../Calendar/MissionCalendarDayCell.swift | 1 + 8 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 NotToDo/NotToDo/Global/Extensions/Date+.swift create mode 100644 NotToDo/NotToDo/Global/Extensions/String+.swift diff --git a/NotToDo/NotToDo.xcodeproj/project.pbxproj b/NotToDo/NotToDo.xcodeproj/project.pbxproj index 914e216..162380c 100644 --- a/NotToDo/NotToDo.xcodeproj/project.pbxproj +++ b/NotToDo/NotToDo.xcodeproj/project.pbxproj @@ -34,6 +34,8 @@ 099F0728296B94790036CF55 /* StatisticsEmptyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099F0727296B94790036CF55 /* StatisticsEmptyTableViewCell.swift */; }; 099F072A296B98B90036CF55 /* SituationTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099F0729296B98B90036CF55 /* SituationTitleView.swift */; }; 099F073D296C2F770036CF55 /* CustomSegmentedControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099F073C296C2F770036CF55 /* CustomSegmentedControl.swift */; }; + 09AF3FD229719DD900518D52 /* String+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09AF3FD129719DD900518D52 /* String+.swift */; }; + 09AF3FD429719E2200518D52 /* Date+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09AF3FD329719E2200518D52 /* Date+.swift */; }; 09D3C535296FFD3500F1488D /* SituationStasticsResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D3C534296FFD3500F1488D /* SituationStasticsResponseDTO.swift */; }; 09D3C538296FFD7C00F1488D /* AchieveAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D3C537296FFD7C00F1488D /* AchieveAPI.swift */; }; 09D3C53D29700DC800F1488D /* AchieveService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D3C53C29700DC800F1488D /* AchieveService.swift */; }; @@ -171,6 +173,8 @@ 099F0727296B94790036CF55 /* StatisticsEmptyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatisticsEmptyTableViewCell.swift; sourceTree = ""; }; 099F0729296B98B90036CF55 /* SituationTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SituationTitleView.swift; sourceTree = ""; }; 099F073C296C2F770036CF55 /* CustomSegmentedControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomSegmentedControl.swift; sourceTree = ""; }; + 09AF3FD129719DD900518D52 /* String+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+.swift"; sourceTree = ""; }; + 09AF3FD329719E2200518D52 /* Date+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+.swift"; sourceTree = ""; }; 09D3C534296FFD3500F1488D /* SituationStasticsResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SituationStasticsResponseDTO.swift; sourceTree = ""; }; 09D3C537296FFD7C00F1488D /* AchieveAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AchieveAPI.swift; sourceTree = ""; }; 09D3C53C29700DC800F1488D /* AchieveService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AchieveService.swift; sourceTree = ""; }; @@ -464,6 +468,8 @@ 3B3405DD295B162600D44722 /* UITabBar+.swift */, 3BED5327295C018700157A3B /* adjust+.swift */, 3B5B34AB29618441002E1161 /* UIButton+.swift */, + 09AF3FD129719DD900518D52 /* String+.swift */, + 09AF3FD329719E2200518D52 /* Date+.swift */, 3B576323296403CB00E03637 /* UILabel+.swift */, 3B4187CE296D342900F0FBF4 /* UIViewController+.swift */, 3B882606296DDC0E00A51B50 /* UIDevice+.swift */, @@ -1220,6 +1226,7 @@ 3B162874295AD7860077AE7B /* AppDelegate.swift in Sources */, 3BEF92AF29686A8E0090A290 /* HomeCalendarCollectionViewCell.swift in Sources */, 096BE0172966A142009ED396 /* CustomTabBarCell.swift in Sources */, + 09AF3FD429719E2200518D52 /* Date+.swift in Sources */, 3BE07017296F44D3002CC50A /* MyInfoViewController.swift in Sources */, 3B0155872971512C00E7BBF1 /* MissionCalendarDayCell.swift in Sources */, 3BE07006296F43A2002CC50A /* UIStackView+.swift in Sources */, @@ -1244,6 +1251,7 @@ 3BBE56E7296C214600771DE4 /* FirstOnboardingView.swift in Sources */, 09F695D9296C332D00877EA7 /* CompositionalLayout.swift in Sources */, 3B4B90C62965CB8D008C5CA8 /* myInfoUserCollectionViewCell.swift in Sources */, + 09AF3FD229719DD900518D52 /* String+.swift in Sources */, 6C88260F2967D8280005E222 /* AddSituationCollectionViewCell.swift in Sources */, 3B59AFB8296346650050FF49 /* Numbers.swift in Sources */, 6CDC2D212966C86D00BFF5F4 /* AddMissionTextField.swift in Sources */, diff --git a/NotToDo/NotToDo/Global/Extensions/Date+.swift b/NotToDo/NotToDo/Global/Extensions/Date+.swift new file mode 100644 index 0000000..0c14846 --- /dev/null +++ b/NotToDo/NotToDo/Global/Extensions/Date+.swift @@ -0,0 +1,17 @@ +// +// Date+.swift +// NotToDo +// +// Created by JEONGEUN KIM on 2023/01/13. +// + +import Foundation + +extension Date { + func toString() -> String { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy.MM.dd" + dateFormatter.timeZone = TimeZone(identifier: "UTC") + return dateFormatter.string(from: self) + } +} diff --git a/NotToDo/NotToDo/Global/Extensions/String+.swift b/NotToDo/NotToDo/Global/Extensions/String+.swift new file mode 100644 index 0000000..a462d9c --- /dev/null +++ b/NotToDo/NotToDo/Global/Extensions/String+.swift @@ -0,0 +1,23 @@ +// +// String+.swift +// NotToDo +// +// Created by JEONGEUN KIM on 2023/01/13. +// + +import Foundation + +extension String { + + func toDate() -> Date? { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy.MM.dd" + dateFormatter.timeZone = TimeZone(identifier: "UTC") + if let date = dateFormatter.date(from: self) { + return date + } else { + return nil + } + } +} + diff --git a/NotToDo/NotToDo/Network/DataModel/Achieve/AchieveCalendarResponseDTO.swift b/NotToDo/NotToDo/Network/DataModel/Achieve/AchieveCalendarResponseDTO.swift index 1b31549..05fef48 100644 --- a/NotToDo/NotToDo/Network/DataModel/Achieve/AchieveCalendarResponseDTO.swift +++ b/NotToDo/NotToDo/Network/DataModel/Achieve/AchieveCalendarResponseDTO.swift @@ -10,4 +10,20 @@ import Foundation struct AchieveCalendarResponseDTO: Codable { let actionDate: String let count: Int + + func toDate(dateString: String) -> Date? { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy.MM.dd" + dateFormatter.timeZone = TimeZone(identifier: "UTC") + if let date = dateFormatter.date(from: dateString) { + return date + } else { + return nil + } + } + + func convert() -> [Date:Int] { + guard let date = self.toDate(dateString: actionDate) else { return [:]} + return [date:count] + } } diff --git a/NotToDo/NotToDo/Presentation/AchievementScene/ViewControllers/AchievementViewController.swift b/NotToDo/NotToDo/Presentation/AchievementScene/ViewControllers/AchievementViewController.swift index 1e72a81..aa6d639 100644 --- a/NotToDo/NotToDo/Presentation/AchievementScene/ViewControllers/AchievementViewController.swift +++ b/NotToDo/NotToDo/Presentation/AchievementScene/ViewControllers/AchievementViewController.swift @@ -21,7 +21,7 @@ final class AchievementViewController: UIViewController { situationView.isHidden = !self.missionView.isHidden } } - + // MARK: - UI Components @@ -42,12 +42,13 @@ final class AchievementViewController: UIViewController { var missionList: [MissionStatistcsResponseDTO] = [] var dataSource: [String: Int] = [:] + // MARK: - View Life Cycle override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) requestAchieveAPI() - // requestMonthAPI(month: month) + requestMonthAPI(month: dateFormatter.string(from: calendarView.calendar.today!)) } override func viewDidLoad() { @@ -78,7 +79,7 @@ extension AchievementViewController { $0.monthCalendarClosure = { [self] result in let month = result self.reloadMonthData(month: month) - } + } $0.layer.borderWidth = 1 $0.layer.borderColor = UIColor.nottodoGray2?.cgColor $0.calendar.delegate = self @@ -120,7 +121,13 @@ extension AchievementViewController { AchieveAPI.shared.getAchieveCalendar(month: month) { [self] result in switch result { case let .success(data): - guard data is [AchieveCalendarResponseDTO] else { return } + guard let data = data as? [AchieveCalendarResponseDTO] else { return } + self.dataSource = [:] + for item in data { + self.dataSource[item.actionDate] = item.count + } + calendarView.calendar.reloadData() + case .requestErr: print("requestErr") case .pathErr: @@ -256,42 +263,24 @@ extension AchievementViewController: FSCalendarDelegate { extension AchievementViewController: FSCalendarDataSource { - // 서버에서 넘어온 dateString이랑 이 메서드의 date를 잘 매칭시켜줘야 함 - // date 매칭된 것에 맞게 데이터를 넘겨줘야 함 func calendar(_ calendar: FSCalendar, cellFor date: Date, at position: FSCalendarMonthPosition) -> FSCalendarCell { let cell = calendar.dequeueReusableCell(withIdentifier: String(describing: MissionCalendarDayCell.self), for: date, at: position) as! MissionCalendarDayCell -// switch cell.state { -// case .none: -// return -// case .step1: -// return -// case .step2: -// return -// case .step3: -// return -// default: -// break -// } - // MARK: 서버에서 넘어온 값에 따라 셀 상태 변화시켜주기 - // Date : Int(Enum) - /* - NotToDoCalendarCell에 가보면 Enum이 보일 것임 - 프로젝트 상황에 따라 적절하게 바꿔서 사용하기 - - 현재는 5개의 case가 있음 - - none, step1, step2, step3, bordered - - case에 따라서 backgroundColor 변화시키는 식으로 구현되어 있는데 UI 디테일을 살리고 싶으면 - 그냥 case에 따라 이미지를 넣는 것이 더 쉬움 - */ - - // 캘린더 셀 설정해주는 코드 : CollectionViewCell이랑 동일하게 생각하면 됨 - cell.configure(.step1) + if let count = self.dataSource[date.toString()] { + switch count { + case 0: + cell.configure(.none) + case 1: + cell.configure(.step1) + case 2: + cell.configure(.step2) + case 3: + cell.configure(.step3) + default: + cell.configure(.none) + } + } return cell } } -extension AchievementViewController: FSCalendarDelegateAppearance { - -} diff --git a/NotToDo/NotToDo/Presentation/AchievementScene/Views/CustomCalendarView.swift b/NotToDo/NotToDo/Presentation/AchievementScene/Views/CustomCalendarView.swift index 28aa8fb..9934fa9 100644 --- a/NotToDo/NotToDo/Presentation/AchievementScene/Views/CustomCalendarView.swift +++ b/NotToDo/NotToDo/Presentation/AchievementScene/Views/CustomCalendarView.swift @@ -26,7 +26,7 @@ class CustomCalendar: UIView { lazy var dateFormatter = DateFormatter() var monthData: [AchieveCalendarResponseDTO] = [] var monthCalendarClosure: ((_ month:String) -> Void)? - + // MARK: - View Life Cycle override init(frame: CGRect) { diff --git a/NotToDo/NotToDo/Presentation/AchievementScene/Views/MissionStatisticsView.swift b/NotToDo/NotToDo/Presentation/AchievementScene/Views/MissionStatisticsView.swift index af6c703..af49aff 100644 --- a/NotToDo/NotToDo/Presentation/AchievementScene/Views/MissionStatisticsView.swift +++ b/NotToDo/NotToDo/Presentation/AchievementScene/Views/MissionStatisticsView.swift @@ -25,7 +25,6 @@ class MissionStatisticsView: UIView { override init(frame: CGRect) { super.init(frame: .zero) - // setUI() register() setLayout() } diff --git a/NotToDo/NotToDo/Presentation/Common/Calendar/MissionCalendarDayCell.swift b/NotToDo/NotToDo/Presentation/Common/Calendar/MissionCalendarDayCell.swift index da51873..ab38e73 100644 --- a/NotToDo/NotToDo/Presentation/Common/Calendar/MissionCalendarDayCell.swift +++ b/NotToDo/NotToDo/Presentation/Common/Calendar/MissionCalendarDayCell.swift @@ -83,5 +83,6 @@ final class MissionCalendarDayCell: FSCalendarCell { extension MissionCalendarDayCell { func configure(_ state: ToDoState) { self.state = state + updateUI() } }