Skip to content

Commit

Permalink
Merge pull request #63 from TeamHY2/Feature/#28-CalendarView
Browse files Browse the repository at this point in the history
[Feature] CalendarView 구현
  • Loading branch information
Seokki-Kwon authored Nov 8, 2024
2 parents 3fd019a + 05a06eb commit f0e8076
Show file tree
Hide file tree
Showing 40 changed files with 621 additions and 31 deletions.
49 changes: 47 additions & 2 deletions HongikYeolgong2.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@
47F635052CC3EC1A0034EAA9 /* Department.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F635042CC3EC1A0034EAA9 /* Department.swift */; };
47F79B2E2CCCB7AA00DD0899 /* TimePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F79B2D2CCCB7AA00DD0899 /* TimePickerView.swift */; };
47F79B302CCCB7FC00DD0899 /* TimePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F79B2F2CCCB7FC00DD0899 /* TimePicker.swift */; };
5E847A6C2CDBD49A0034C2A7 /* CalendarCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E847A6B2CDBD49A0034C2A7 /* CalendarCell.swift */; };
5E847A6E2CDBD4B60034C2A7 /* CalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E847A6D2CDBD4B60034C2A7 /* CalendarView.swift */; };
5E847A702CDBD4F10034C2A7 /* CalendarMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E847A6F2CDBD4F10034C2A7 /* CalendarMapper.swift */; };
5E847A742CDBD52E0034C2A7 /* CalendarDataInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E847A732CDBD52E0034C2A7 /* CalendarDataInteractor.swift */; };
5E847A772CDBD5590034C2A7 /* AllStudyRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E847A762CDBD5590034C2A7 /* AllStudyRecord.swift */; };
5E847A7D2CDBD7120034C2A7 /* CalendarCountAllResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E847A7C2CDBD7120034C2A7 /* CalendarCountAllResponseDTO.swift */; };
98B5F00A2CDB362C007CF5FA /* Secrets-dev.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 98B5F0092CDB362C007CF5FA /* Secrets-dev.xcconfig */; };
98B5F00C2CDB6226007CF5FA /* StudyTimeResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B5F00B2CDB6226007CF5FA /* StudyTimeResponseDTO.swift */; };
98B5F00F2CDB652A007CF5FA /* StudyTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B5F00E2CDB652A007CF5FA /* StudyTime.swift */; };
Expand Down Expand Up @@ -260,6 +266,12 @@
47F635042CC3EC1A0034EAA9 /* Department.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Department.swift; sourceTree = "<group>"; };
47F79B2D2CCCB7AA00DD0899 /* TimePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimePickerView.swift; sourceTree = "<group>"; };
47F79B2F2CCCB7FC00DD0899 /* TimePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimePicker.swift; sourceTree = "<group>"; };
5E847A6B2CDBD49A0034C2A7 /* CalendarCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarCell.swift; sourceTree = "<group>"; };
5E847A6D2CDBD4B60034C2A7 /* CalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarView.swift; sourceTree = "<group>"; };
5E847A6F2CDBD4F10034C2A7 /* CalendarMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarMapper.swift; sourceTree = "<group>"; };
5E847A732CDBD52E0034C2A7 /* CalendarDataInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarDataInteractor.swift; sourceTree = "<group>"; };
5E847A762CDBD5590034C2A7 /* AllStudyRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllStudyRecord.swift; sourceTree = "<group>"; };
5E847A7C2CDBD7120034C2A7 /* CalendarCountAllResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarCountAllResponseDTO.swift; sourceTree = "<group>"; };
98B5F0092CDB362C007CF5FA /* Secrets-dev.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Secrets-dev.xcconfig"; sourceTree = "<group>"; };
98B5F00B2CDB6226007CF5FA /* StudyTimeResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudyTimeResponseDTO.swift; sourceTree = "<group>"; };
98B5F00E2CDB652A007CF5FA /* StudyTime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudyTime.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -419,6 +431,7 @@
478004412CCA924200FFAF00 /* StudySessionMapper.swift */,
98B5F0122CDBB905007CF5FA /* StudyTimeMapper.swift */,
478F844A2CD35AF40097CAA1 /* RankingMapper.swift */,
5E847A6F2CDBD4F10034C2A7 /* CalendarMapper.swift */,
);
path = Mapper;
sourceTree = "<group>";
Expand Down Expand Up @@ -576,7 +589,11 @@
47A147382CA1380900A91F66 /* Entities */ = {
isa = PBXGroup;
children = (

5E847A752CDBD5490034C2A7 /* Calendar */,

98B5F00D2CDB64D4007CF5FA /* Record */,

478F84452CD358F50097CAA1 /* Ranking */,
478FBCA12CD1397600256012 /* User */,
4780043D2CCA8FF800FFAF00 /* WeeklyStudy */,
Expand All @@ -596,6 +613,7 @@
47A1473A2CA13DD000A91F66 /* DTO */ = {
isa = PBXGroup;
children = (
5E847A7B2CDBD7040034C2A7 /* Calendar */,
478F84422CD3506D0097CAA1 /* Ranking */,
478F843F2CD33F4D0097CAA1 /* Weekly */,
4786A10D2CCA3506008635A4 /* StudySession */,
Expand All @@ -615,6 +633,7 @@
4786A0EB2CC9E2BC008635A4 /* UserPermissionsInteractor.swift */,
47E250702CCF274400267897 /* WeeklyStudyInteractor.swift */,
478F84382CD3176E0097CAA1 /* RankingDataInteractor.swift */,
5E847A732CDBD52E0034C2A7 /* CalendarDataInteractor.swift */,
);
path = Interactors;
sourceTree = "<group>";
Expand Down Expand Up @@ -854,18 +873,37 @@
path = Models;
sourceTree = "<group>";
};

5E847A752CDBD5490034C2A7 /* Calendar */ = {
isa = PBXGroup;
children = (
5E847A762CDBD5590034C2A7 /* AllStudyRecord.swift */,
);
path = Calendar;
sourceTree = "<group>";
};
5E847A7B2CDBD7040034C2A7 /* Calendar */ = {
isa = PBXGroup;
children = (
5E847A7C2CDBD7120034C2A7 /* CalendarCountAllResponseDTO.swift */,
);
path = Calendar;

98B5F00D2CDB64D4007CF5FA /* Record */ = {
isa = PBXGroup;
children = (
98B5F00E2CDB652A007CF5FA /* StudyTime.swift */,
);
path = Record;

sourceTree = "<group>";
};
98F9D8422CDA2DE100DE12BB /* Component */ = {
isa = PBXGroup;
children = (
98F9D8452CDA2E6D00DE12BB /* RecordCell.swift */,
5E847A6B2CDBD49A0034C2A7 /* CalendarCell.swift */,
5E847A6D2CDBD4B60034C2A7 /* CalendarView.swift */,
);
path = Component;
sourceTree = "<group>";
Expand Down Expand Up @@ -1063,6 +1101,7 @@
98B5F00C2CDB6226007CF5FA /* StudyTimeResponseDTO.swift in Sources */,
47BACCF72CA164BA00295DAC /* Font+.swift in Sources */,
4786A1102CCA351A008635A4 /* WeeklyStudySessionDTO.swift in Sources */,
5E847A742CDBD52E0034C2A7 /* CalendarDataInteractor.swift in Sources */,
470722FA2CBC0A870046469F /* Constants.swift in Sources */,
478F84492CD359260097CAA1 /* WeeklyRanking.swift in Sources */,
4786A0EC2CC9E2BC008635A4 /* UserPermissionsInteractor.swift in Sources */,
Expand All @@ -1079,16 +1118,19 @@
473E8EBA2CCEA702000F102C /* StudySessionResponseDTO.swift in Sources */,
4752A27D2CB96EB00073B784 /* CancleBag.swift in Sources */,
4736719F2CB120A600527896 /* WeeklyStudyView.swift in Sources */,
5E847A7D2CDBD7120034C2A7 /* CalendarCountAllResponseDTO.swift in Sources */,
4780044C2CCAAD4F00FFAF00 /* WeekDay.swift in Sources */,
47E250732CCF2BED00267897 /* WiseSaying.swift in Sources */,
47A1477E2CA159E300A91F66 /* SplashView.swift in Sources */,
5E847A702CDBD4F10034C2A7 /* CalendarMapper.swift in Sources */,
475B86E32CA1AF40000534B2 /* SettingView.swift in Sources */,
470723052CBC180D0046469F /* NetworkError.swift in Sources */,
47BE30E52CC81A9E0015D973 /* URLRequest+.swift in Sources */,
473671A52CB13D8100527896 /* SafeArea.swift in Sources */,
471940C82CAFCB1B00426D30 /* SizeCheckModifier.swift in Sources */,
473E8EB82CCEA5FB000F102C /* StudySessionRequestDTO.swift in Sources */,
47A540732CD0D90F00DC40D0 /* Nickname.swift in Sources */,
5E847A6C2CDBD49A0034C2A7 /* CalendarCell.swift in Sources */,
47F634FE2CC3E8A40034EAA9 /* NicknameCheckDTO.swift in Sources */,
4763FFAF2CB90AE000990336 /* AppState.swift in Sources */,
4786A1092CCA346F008635A4 /* StudySessionRepository.swift in Sources */,
Expand All @@ -1111,6 +1153,7 @@
473E8EB42CCE6827000F102C /* TimeInterval+.swift in Sources */,
4763FFB32CB90E3800990336 /* InteractorsContainer.swift in Sources */,
470723182CBC29510046469F /* AuthenticationService.swift in Sources */,
5E847A6E2CDBD4B60034C2A7 /* CalendarView.swift in Sources */,
47BE30E32CC813BB0015D973 /* KeyChainManager.swift in Sources */,
4786A10C2CCA34A7008635A4 /* StudySessionRepositoryImpl.swift in Sources */,
470723132CBC1BF10046469F /* BaseResponse.swift in Sources */,
Expand All @@ -1119,6 +1162,7 @@
47CA17252CC9336100CBB251 /* StudyPeriodView.swift in Sources */,
4763FFB82CB9134D00990336 /* Store.swift in Sources */,
47A147802CA15A4E00A91F66 /* OnboardingView.swift in Sources */,
5E847A772CDBD5590034C2A7 /* AllStudyRecord.swift in Sources */,
478F844D2CD3629A0097CAA1 /* RankingListView.swift in Sources */,
470723032CBC17E40046469F /* NetworkService.swift in Sources */,
470723012CBC16680046469F /* AuthEndpoint.swift in Sources */,
Expand Down Expand Up @@ -1170,6 +1214,7 @@
/* Begin XCBuildConfiguration section */
47B1D4CA2C9CB1760071B62B /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 98B5F0092CDB362C007CF5FA /* Secrets-dev.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
Expand Down Expand Up @@ -1323,7 +1368,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.teamHY2.HongikYeolgong2;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.teamHY2.HongikYeolgong2 1730730522";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = HY2_Development;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
Expand Down Expand Up @@ -1370,7 +1415,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.teamHY2.HongikYeolgong2;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.teamHY2.HongikYeolgong2 1730730522";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = HY2_Development;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1540"
version = "1.7">
version = "1.8">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
Expand Down
3 changes: 2 additions & 1 deletion HongikYeolgong2/Core/AppEnviroment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ extension AppEnviroment {
appState: appState,
studySessionRepository: remoteRepository.studySessionRepository
),
rankingDataInteractor: RankingDataInteractorImpl(studySessionRepository: remoteRepository.studySessionRepository, weeklyRepository: remoteRepository.weeklyRepository)
rankingDataInteractor: RankingDataInteractorImpl(studySessionRepository: remoteRepository.studySessionRepository, weeklyRepository: remoteRepository.weeklyRepository),
calendarDataInteractor: CalendarDataInteractorImpl(appstate: appState, studySessionRepository: remoteRepository.studySessionRepository)
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

import Foundation

struct CalendarCountAllResponseDTO: Decodable {
let date: String
let studyCount: Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ final class StudySessionRepositoryImpl: StudySessionRepository {
}.eraseToAnyPublisher()
}


func getAllStudyRecords() -> AnyPublisher<[AllStudyRecord], NetworkError> {
return Future<[AllStudyRecord], NetworkError> { promise in
Task {
do {
let response: BaseResponse<[CalendarCountAllResponseDTO]> = try await NetworkService.shared.request(endpoint: WeeklyEndpoint.getAllStudyRecords)
promise(.success(response.data.map { $0.toEntity() }))

} catch let error as NetworkError {
promise(.failure(error))

// 연간, 월간, 투데이, 학기 공부 시간 조회
func getStudyTime() -> AnyPublisher<StudyTime, NetworkError> {
return Future<StudyTime, NetworkError> { promise in
Expand All @@ -72,6 +83,7 @@ final class StudySessionRepositoryImpl: StudySessionRepository {
promise(.success(response.data.toEntity()))
} catch let error as NetworkError {
print(error.message)

}
}
}.eraseToAnyPublisher()
Expand Down
12 changes: 12 additions & 0 deletions HongikYeolgong2/Domain/Entities/Calendar/AllStudyRecord.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

import Foundation

struct AllStudyRecord {
let day: String
let month: String
let year: String
let date: Date
let studyCount: Int
}


28 changes: 28 additions & 0 deletions HongikYeolgong2/Domain/Interactors/CalendarDataInteractor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

import SwiftUI

protocol CalendarDataInteractor {
func getAllStudy(studyRecords: Binding<[AllStudyRecord]>)
}


final class CalendarDataInteractorImpl: CalendarDataInteractor {
private let appstate: Store<AppState>
private let cancleBag = CancelBag()
private let studySessionRepository: StudySessionRepository

init(appstate: Store<AppState>, studySessionRepository: StudySessionRepository) {
self.appstate = appstate
self.studySessionRepository = studySessionRepository
}

func getAllStudy(studyRecords: Binding<[AllStudyRecord]>) {
studySessionRepository
.getAllStudyRecords()
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { _ in }) {
studyRecords.wrappedValue = $0
}
.store(in: cancleBag)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,9 @@ protocol StudySessionRepository {
func uploadStudyRecord(startTime: Date, endTime: Date) -> AnyPublisher<StudySessionResponseDTO, NetworkError>
func getWiseSaying() -> AnyPublisher<WiseSaying, NetworkError>
func getWeeklyRanking(yearWeek: Int) -> AnyPublisher<WeeklyRanking, NetworkError>

func getAllStudyRecords() -> AnyPublisher<[AllStudyRecord], NetworkError>

func getStudyTime() -> AnyPublisher<StudyTime, NetworkError>

}
8 changes: 8 additions & 0 deletions HongikYeolgong2/Domain/Mapper/CalendarMapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

import Foundation

extension CalendarCountAllResponseDTO {
func toEntity() -> AllStudyRecord {
.init(day: date.toDayofDate(), month: date.toMonthofDate(), year: date.toYearofDate(), date: date.toDate() ?? Date.now, studyCount: studyCount)
}
}
17 changes: 8 additions & 9 deletions HongikYeolgong2/Injected/InteractorsContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,21 @@ extension DIContainer {
let userDataInteractor: UserDataInteractor
let studyTimeInteractor: StudyTimeInteractor
let studySessionInteractor: StudySessionInteractor
let userPermissionsInteractor: UserPermissionsInteractor
let userPermissionsInteractor: UserPermissionsInteractor
let weeklyStudyInteractor: WeeklyStudyInteractor
let rankingDataInteractor: RankingDataInteractor
let calendarDataInteractor: CalendarDataInteractor

init(userDataInteractor: UserDataInteractor,
studyTimeInteractor: StudyTimeInteractor,
studySessionInteractor: StudySessionInteractor,
userPermissionsInteractor: UserPermissionsInteractor,
weeklyStudyInteractor: WeeklyStudyInteractor,
rankingDataInteractor: RankingDataInteractor) {


init(userDataInteractor: UserDataInteractor, studySessionInteractor: StudySessionInteractor, userPermissionsInteractor: UserPermissionsInteractor, weeklyStudyInteractor: WeeklyStudyInteractor, rankingDataInteractor: RankingDataInteractor, calendarDataInteractor: CalendarDataInteractor) {

self.userDataInteractor = userDataInteractor
self.studyTimeInteractor = studyTimeInteractor
self.studySessionInteractor = studySessionInteractor
self.userPermissionsInteractor = userPermissionsInteractor
self.weeklyStudyInteractor = weeklyStudyInteractor
self.rankingDataInteractor = rankingDataInteractor
self.calendarDataInteractor = calendarDataInteractor
}

static let `default` = Self(
Expand All @@ -41,7 +39,8 @@ extension DIContainer {
studySessionInteractor: StudySessionInteractorImpl(appState: Store<AppState>(AppState()), studySessionRepository: StudySessionRepositoryImpl()),
userPermissionsInteractor: RealUserPermissionsInteractor(appState: Store<AppState>(AppState()), openAppSetting: {}),
weeklyStudyInteractor: WeeklyStudyInteractorImpl(appState: Store<AppState>(AppState()), studySessionRepository: StudySessionRepositoryImpl()),
rankingDataInteractor: RankingDataInteractorImpl(studySessionRepository: StudySessionRepositoryImpl(), weeklyRepository: WeeklyRepositoryImpl())
rankingDataInteractor: RankingDataInteractorImpl(studySessionRepository: StudySessionRepositoryImpl(), weeklyRepository: WeeklyRepositoryImpl()),
calendarDataInteractor: CalendarDataInteractorImpl(appstate: Store<AppState>(AppState()), studySessionRepository: StudySessionRepositoryImpl())
)
}
}
Expand Down
Loading

0 comments on commit f0e8076

Please sign in to comment.