diff --git a/LionHeart-iOS/LionHeart-iOS.xcodeproj/project.pbxproj b/LionHeart-iOS/LionHeart-iOS.xcodeproj/project.pbxproj index 10f9f422..e3b9f558 100644 --- a/LionHeart-iOS/LionHeart-iOS.xcodeproj/project.pbxproj +++ b/LionHeart-iOS/LionHeart-iOS.xcodeproj/project.pbxproj @@ -17,9 +17,7 @@ 4A8980CE2A617F7100746C58 /* CollectionHeaderViewRegisterDequeueProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A8980CD2A617F7100746C58 /* CollectionHeaderViewRegisterDequeueProtocol.swift */; }; 4A8980D02A61850500746C58 /* MyPageAppSettingCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A8980CF2A61850500746C58 /* MyPageAppSettingCollectionViewCell.swift */; }; 4AD216402A69AC1E00C9F2F2 /* MyPageResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AD2163F2A69AC1E00C9F2F2 /* MyPageResponse.swift */; }; - 4AD6A34C2AB1AB6700977224 /* BookmarkAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AD6A34B2AB1AB6700977224 /* BookmarkAPI.swift */; }; 4AD6AE1A2A68436B00A3D745 /* ArticleListByCategoryResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AD6AE192A68436B00A3D745 /* ArticleListByCategoryResponse.swift */; }; - 4AE19A172A65864F00C1DB7E /* BookmarkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE19A162A65864F00C1DB7E /* BookmarkService.swift */; }; 4AE19A1A2A65886100C1DB7E /* BookmarkReponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE19A192A65886100C1DB7E /* BookmarkReponse.swift */; }; 4AE19A1E2A6597E700C1DB7E /* BookmarkRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE19A1D2A6597E700C1DB7E /* BookmarkRequest.swift */; }; 4AE19A1F2A66F2E200C1DB7E /* BookmarkDetailCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A8980C12A5FD6AF00746C58 /* BookmarkDetailCollectionViewCell.swift */; }; @@ -53,7 +51,6 @@ B57BEB6C2A6149AD00D1727C /* NetworkRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEB6B2A6149AD00D1727C /* NetworkRequest.swift */; }; B57BEB6E2A6275D600D1727C /* Serviceable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEB6D2A6275D600D1727C /* Serviceable.swift */; }; B57BEB702A6275F500D1727C /* ViewControllerServiceable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEB6F2A6275F500D1727C /* ViewControllerServiceable.swift */; }; - B57FEE2C2AA904D800ED6299 /* AuthMyPageServiceWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57FEE2B2AA904D800ED6299 /* AuthMyPageServiceWrapper.swift */; }; B598926F2A56C21800CE1FEB /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = B598926E2A56C21800CE1FEB /* FirebaseAnalytics */; }; B59892712A56C21800CE1FEB /* FirebaseAnalyticsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = B59892702A56C21800CE1FEB /* FirebaseAnalyticsSwift */; }; B59892732A56C21800CE1FEB /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = B59892722A56C21800CE1FEB /* FirebaseCrashlytics */; }; @@ -87,7 +84,6 @@ B59893112A5D039B00CE1FEB /* ArticleBlockType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59893102A5D039B00CE1FEB /* ArticleBlockType.swift */; }; B59893132A5D3A4D00CE1FEB /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59893122A5D3A4D00CE1FEB /* NetworkError.swift */; }; B59893162A5D40FC00CE1FEB /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = B59893152A5D40FC00CE1FEB /* Kingfisher */; }; - B59893192A5D41F600CE1FEB /* KingfisherService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59893182A5D41F600CE1FEB /* KingfisherService.swift */; }; B5C6A2B22A5DB0B10021BE5E /* ArticleDetailTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C6A2B12A5DB0B10021BE5E /* ArticleDetailTableView.swift */; }; B5C6A2B42A5DB11A0021BE5E /* ThumnailTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C6A2B32A5DB11A0021BE5E /* ThumnailTableViewCell.swift */; }; B5C6A2B62A5DD5FE0021BE5E /* TitleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C6A2B52A5DD5FE0021BE5E /* TitleTableViewCell.swift */; }; @@ -98,7 +94,6 @@ B5C6A2C22A5DEA1B0021BE5E /* CopyRightTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C6A2C12A5DEA1B0021BE5E /* CopyRightTableViewCell.swift */; }; B5C6A2C82A5EF4EB0021BE5E /* ArticleDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C6A2C72A5EF4EB0021BE5E /* ArticleDetail.swift */; }; B5F323E92A6A8F0000047869 /* CurriculumWeekBackgroundDummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F323E82A6A8F0000047869 /* CurriculumWeekBackgroundDummy.swift */; }; - C004D4992AAD8F880087F044 /* MyPageAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C004D4982AAD8F880087F044 /* MyPageAPI.swift */; }; C00780B72A5FFE0E0043EB36 /* UILabel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00780B62A5FFE0E0043EB36 /* UILabel+.swift */; }; C00780BA2A60149D0043EB36 /* LHTodayArticleTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00780B92A60149D0043EB36 /* LHTodayArticleTitle.swift */; }; C06E381B2A65346700B00600 /* UserDefaultToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = C06E381A2A65346700B00600 /* UserDefaultToken.swift */; }; @@ -106,11 +101,27 @@ C06E38212A65351600B00600 /* SignUpRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C06E38202A65351600B00600 /* SignUpRequest.swift */; }; C06E38232A65353F00B00600 /* LoginType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C06E38222A65353F00B00600 /* LoginType.swift */; }; C06E38282A662D8700B00600 /* TodayArticleResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = C06E38272A662D8700B00600 /* TodayArticleResponse.swift */; }; - C06E382A2A662E3700B00600 /* ArticleService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C06E38292A662E3700B00600 /* ArticleService.swift */; }; C07CB81A2A62C54D000198CC /* TodayModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07CB8192A62C54D000198CC /* TodayModel.swift */; }; C07CB81E2A62C5B1000198CC /* TodayArticleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07CB81D2A62C5B1000198CC /* TodayArticleView.swift */; }; + C0856B652ABFB8640026D9F8 /* TodayManagerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B642ABFB8640026D9F8 /* TodayManagerImpl.swift */; }; + C0856B692ABFB9140026D9F8 /* ArticleServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B682ABFB9140026D9F8 /* ArticleServiceImpl.swift */; }; + C0856B6B2ABFBC9D0026D9F8 /* ArticleDetailManagerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B6A2ABFBC9D0026D9F8 /* ArticleDetailManagerImpl.swift */; }; + C0856B6D2ABFBD840026D9F8 /* BookmarkServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B6C2ABFBD840026D9F8 /* BookmarkServiceImpl.swift */; }; + C0856B6F2ABFBFF00026D9F8 /* ChallengeServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B6E2ABFBFF00026D9F8 /* ChallengeServiceImpl.swift */; }; + C0856B712ABFC0FB0026D9F8 /* ChallengeManagerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B702ABFC0FB0026D9F8 /* ChallengeManagerImpl.swift */; }; + C0856B732ABFC3070026D9F8 /* BookmarkMangerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B722ABFC3070026D9F8 /* BookmarkMangerImpl.swift */; }; + C0856B752ABFC4CB0026D9F8 /* MyPageManagerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B742ABFC4CB0026D9F8 /* MyPageManagerImpl.swift */; }; + C0856B772ABFC4EA0026D9F8 /* MyPageServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B762ABFC4EA0026D9F8 /* MyPageServiceImpl.swift */; }; + C0856B792ABFC56E0026D9F8 /* AuthServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B782ABFC56E0026D9F8 /* AuthServiceImpl.swift */; }; + C0856B7B2ABFC9640026D9F8 /* SplashManagerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B7A2ABFC9640026D9F8 /* SplashManagerImpl.swift */; }; + C0856B7D2ABFCA330026D9F8 /* LoginMangerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B7C2ABFCA330026D9F8 /* LoginMangerImpl.swift */; }; + C0856B7F2ABFCBF20026D9F8 /* ArticleListByCategoryMangerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B7E2ABFCBF20026D9F8 /* ArticleListByCategoryMangerImpl.swift */; }; + C0856B812ABFCD830026D9F8 /* OnboardingManagerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B802ABFCD830026D9F8 /* OnboardingManagerImpl.swift */; }; + C0856B832ABFCFBE0026D9F8 /* CurriculumServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B822ABFCFBE0026D9F8 /* CurriculumServiceImpl.swift */; }; + C0856B852ABFD0F50026D9F8 /* CurriculumManagerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B842ABFD0F50026D9F8 /* CurriculumManagerImpl.swift */; }; + C0856B872ABFD24E0026D9F8 /* CurriculumListManagerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B862ABFD24E0026D9F8 /* CurriculumListManagerImpl.swift */; }; + C0856B892ABFDA240026D9F8 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0856B882ABFDA240026D9F8 /* Badge.swift */; }; C0903CFF2AAAD7E00014786F /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0903CFE2AAAD7E00014786F /* APIService.swift */; }; - C0903D022AAAD86A0014786F /* AuthAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0903D012AAAD86A0014786F /* AuthAPI.swift */; }; C09217682A605DEE00231C66 /* OnboardingFetalNicknameTextFieldResultType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C09217662A605DEE00231C66 /* OnboardingFetalNicknameTextFieldResultType.swift */; }; C09217692A605DEE00231C66 /* OnboardingPregnancyTextFieldResultType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C09217672A605DEE00231C66 /* OnboardingPregnancyTextFieldResultType.swift */; }; C09217732A61895A00231C66 /* UIWindow+.swift in Sources */ = {isa = PBXBuildFile; fileRef = C09217722A61895A00231C66 /* UIWindow+.swift */; }; @@ -139,9 +150,6 @@ C0DF03552A5A9BD60037F740 /* ArticleListByCategoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DF03542A5A9BD60037F740 /* ArticleListByCategoryView.swift */; }; C0DF03592A5A9BF80037F740 /* ArticleCategoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DF03582A5A9BF80037F740 /* ArticleCategoryViewController.swift */; }; C0DF035B2A5A9C040037F740 /* ArticleCategoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DF035A2A5A9C040037F740 /* ArticleCategoryView.swift */; }; - C0DF035D2A5A9C260037F740 /* ArticleListByWeekTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DF035C2A5A9C260037F740 /* ArticleListByWeekTableViewCell.swift */; }; - C0DF035F2A5A9C330037F740 /* ArticleListByWeekViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DF035E2A5A9C330037F740 /* ArticleListByWeekViewController.swift */; }; - C0DF03612A5A9C400037F740 /* ArticleListByWeekView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DF03602A5A9C400037F740 /* ArticleListByWeekView.swift */; }; C0DF03652A5A9C610037F740 /* ArticleDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DF03642A5A9C610037F740 /* ArticleDetailView.swift */; }; C0DF03672A5A9C680037F740 /* ArticleDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DF03662A5A9C680037F740 /* ArticleDetailViewController.swift */; }; C0DF036B2A5A9C930037F740 /* BookMarkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DF036A2A5A9C930037F740 /* BookMarkView.swift */; }; @@ -178,7 +186,6 @@ C0F62FE72A691FC40003ADFA /* LHLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0F62FE62A691FC40003ADFA /* LHLoadingView.swift */; }; D34280772A66B90C00DA1499 /* UILabelPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = D34280762A66B90C00DA1499 /* UILabelPadding.swift */; }; D342807A2A67F12200DA1499 /* ChallengeDataResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = D34280792A67F12200DA1499 /* ChallengeDataResponse.swift */; }; - D342807C2A67FE4700DA1499 /* ChallengeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D342807B2A67FE4700DA1499 /* ChallengeService.swift */; }; D35272D12A681E13002D7FCB /* ChallengeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D35272D02A681E13002D7FCB /* ChallengeData.swift */; }; D3AB54B62A625A7B0017BF53 /* ArticleListByCategoryHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3AB54B52A625A7B0017BF53 /* ArticleListByCategoryHeaderView.swift */; }; D3AB54C12A62CE3F0017BF53 /* ChallengeDayCheckCollectionViewCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3AB54C02A62CE3F0017BF53 /* ChallengeDayCheckCollectionViewCollectionViewCell.swift */; }; @@ -195,7 +202,6 @@ F4490C072A5CEEA300A6D9D7 /* CurriculumDummyData.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4490C062A5CEEA300A6D9D7 /* CurriculumDummyData.swift */; }; F46522FD2A6048660083FBB2 /* CurriculumImagesByWeek.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46522FC2A6048650083FBB2 /* CurriculumImagesByWeek.swift */; }; F47329E12A66F5D0001605D4 /* CurriculumResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = F47329E02A66F5D0001605D4 /* CurriculumResponse.swift */; }; - F4C60E1D2A66B4CE006BBADE /* CurriculumViewService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4C60E1C2A66B4CE006BBADE /* CurriculumViewService.swift */; }; F4DB30AE2A611C7C00413EB9 /* CurriculumListByWeekViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4DB30AD2A611C7B00413EB9 /* CurriculumListByWeekViewController.swift */; }; F4DB30B02A611C9700413EB9 /* CurriculumListByWeekData.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4DB30AF2A611C9700413EB9 /* CurriculumListByWeekData.swift */; }; F4DB30B42A61250500413EB9 /* CurriculumListByWeekCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4DB30B32A61250500413EB9 /* CurriculumListByWeekCollectionViewCell.swift */; }; @@ -232,7 +238,6 @@ 4A8980CD2A617F7100746C58 /* CollectionHeaderViewRegisterDequeueProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionHeaderViewRegisterDequeueProtocol.swift; sourceTree = ""; }; 4A8980CF2A61850500746C58 /* MyPageAppSettingCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageAppSettingCollectionViewCell.swift; sourceTree = ""; }; 4AD2163F2A69AC1E00C9F2F2 /* MyPageResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageResponse.swift; sourceTree = ""; }; - 4AD6A34B2AB1AB6700977224 /* BookmarkAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkAPI.swift; sourceTree = ""; }; 4AD6AE032A66F83E00A3D745 /* progressbar_2m.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = progressbar_2m.json; sourceTree = ""; }; 4AD6AE052A66F84300A3D745 /* progressbar_3m.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = progressbar_3m.json; sourceTree = ""; }; 4AD6AE072A66F84C00A3D745 /* progressbar_4m.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = progressbar_4m.json; sourceTree = ""; }; @@ -243,7 +248,6 @@ 4AD6AE112A66F87400A3D745 /* progressbar_9m.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = progressbar_9m.json; sourceTree = ""; }; 4AD6AE132A66F87C00A3D745 /* progressbar_10m.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = progressbar_10m.json; sourceTree = ""; }; 4AD6AE192A68436B00A3D745 /* ArticleListByCategoryResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleListByCategoryResponse.swift; sourceTree = ""; }; - 4AE19A162A65864F00C1DB7E /* BookmarkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkService.swift; sourceTree = ""; }; 4AE19A192A65886100C1DB7E /* BookmarkReponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkReponse.swift; sourceTree = ""; }; 4AE19A1D2A6597E700C1DB7E /* BookmarkRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkRequest.swift; sourceTree = ""; }; B51220592A5FAA47006CBE2D /* ImageLiterals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageLiterals.swift; sourceTree = ""; }; @@ -281,7 +285,6 @@ B57BEB6B2A6149AD00D1727C /* NetworkRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkRequest.swift; sourceTree = ""; }; B57BEB6D2A6275D600D1727C /* Serviceable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Serviceable.swift; sourceTree = ""; }; B57BEB6F2A6275F500D1727C /* ViewControllerServiceable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerServiceable.swift; sourceTree = ""; }; - B57FEE2B2AA904D800ED6299 /* AuthMyPageServiceWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthMyPageServiceWrapper.swift; sourceTree = ""; }; B58E8CBD2A6AE0F200FF5202 /* LionHeart-iOSRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "LionHeart-iOSRelease.entitlements"; sourceTree = ""; }; B59892802A56C3F900CE1FEB /* LionHeart-iOSDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "LionHeart-iOSDebug.entitlements"; sourceTree = ""; }; B59892822A56C93400CE1FEB /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; @@ -298,7 +301,6 @@ B598930A2A5BED0E00CE1FEB /* Font.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Font.swift; sourceTree = ""; }; B59893102A5D039B00CE1FEB /* ArticleBlockType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleBlockType.swift; sourceTree = ""; }; B59893122A5D3A4D00CE1FEB /* NetworkError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = ""; }; - B59893182A5D41F600CE1FEB /* KingfisherService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KingfisherService.swift; sourceTree = ""; }; B5C6A2B12A5DB0B10021BE5E /* ArticleDetailTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleDetailTableView.swift; sourceTree = ""; }; B5C6A2B32A5DB11A0021BE5E /* ThumnailTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThumnailTableViewCell.swift; sourceTree = ""; }; B5C6A2B52A5DD5FE0021BE5E /* TitleTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleTableViewCell.swift; sourceTree = ""; }; @@ -309,7 +311,6 @@ B5C6A2C12A5DEA1B0021BE5E /* CopyRightTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyRightTableViewCell.swift; sourceTree = ""; }; B5C6A2C72A5EF4EB0021BE5E /* ArticleDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleDetail.swift; sourceTree = ""; }; B5F323E82A6A8F0000047869 /* CurriculumWeekBackgroundDummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumWeekBackgroundDummy.swift; sourceTree = ""; }; - C004D4982AAD8F880087F044 /* MyPageAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageAPI.swift; sourceTree = ""; }; C00780B62A5FFE0E0043EB36 /* UILabel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+.swift"; sourceTree = ""; }; C00780B92A60149D0043EB36 /* LHTodayArticleTitle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LHTodayArticleTitle.swift; sourceTree = ""; }; C06E381A2A65346700B00600 /* UserDefaultToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultToken.swift; sourceTree = ""; }; @@ -317,11 +318,27 @@ C06E38202A65351600B00600 /* SignUpRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpRequest.swift; sourceTree = ""; }; C06E38222A65353F00B00600 /* LoginType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginType.swift; sourceTree = ""; }; C06E38272A662D8700B00600 /* TodayArticleResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayArticleResponse.swift; sourceTree = ""; }; - C06E38292A662E3700B00600 /* ArticleService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleService.swift; sourceTree = ""; }; C07CB8192A62C54D000198CC /* TodayModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TodayModel.swift; sourceTree = ""; }; C07CB81D2A62C5B1000198CC /* TodayArticleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TodayArticleView.swift; sourceTree = ""; }; + C0856B642ABFB8640026D9F8 /* TodayManagerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayManagerImpl.swift; sourceTree = ""; }; + C0856B682ABFB9140026D9F8 /* ArticleServiceImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleServiceImpl.swift; sourceTree = ""; }; + C0856B6A2ABFBC9D0026D9F8 /* ArticleDetailManagerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleDetailManagerImpl.swift; sourceTree = ""; }; + C0856B6C2ABFBD840026D9F8 /* BookmarkServiceImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkServiceImpl.swift; sourceTree = ""; }; + C0856B6E2ABFBFF00026D9F8 /* ChallengeServiceImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeServiceImpl.swift; sourceTree = ""; }; + C0856B702ABFC0FB0026D9F8 /* ChallengeManagerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeManagerImpl.swift; sourceTree = ""; }; + C0856B722ABFC3070026D9F8 /* BookmarkMangerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkMangerImpl.swift; sourceTree = ""; }; + C0856B742ABFC4CB0026D9F8 /* MyPageManagerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageManagerImpl.swift; sourceTree = ""; }; + C0856B762ABFC4EA0026D9F8 /* MyPageServiceImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageServiceImpl.swift; sourceTree = ""; }; + C0856B782ABFC56E0026D9F8 /* AuthServiceImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthServiceImpl.swift; sourceTree = ""; }; + C0856B7A2ABFC9640026D9F8 /* SplashManagerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashManagerImpl.swift; sourceTree = ""; }; + C0856B7C2ABFCA330026D9F8 /* LoginMangerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMangerImpl.swift; sourceTree = ""; }; + C0856B7E2ABFCBF20026D9F8 /* ArticleListByCategoryMangerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleListByCategoryMangerImpl.swift; sourceTree = ""; }; + C0856B802ABFCD830026D9F8 /* OnboardingManagerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingManagerImpl.swift; sourceTree = ""; }; + C0856B822ABFCFBE0026D9F8 /* CurriculumServiceImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumServiceImpl.swift; sourceTree = ""; }; + C0856B842ABFD0F50026D9F8 /* CurriculumManagerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumManagerImpl.swift; sourceTree = ""; }; + C0856B862ABFD24E0026D9F8 /* CurriculumListManagerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumListManagerImpl.swift; sourceTree = ""; }; + C0856B882ABFDA240026D9F8 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; C0903CFE2AAAD7E00014786F /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; }; - C0903D012AAAD86A0014786F /* AuthAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthAPI.swift; sourceTree = ""; }; C09217662A605DEE00231C66 /* OnboardingFetalNicknameTextFieldResultType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingFetalNicknameTextFieldResultType.swift; sourceTree = ""; }; C09217672A605DEE00231C66 /* OnboardingPregnancyTextFieldResultType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingPregnancyTextFieldResultType.swift; sourceTree = ""; }; C09217722A61895A00231C66 /* UIWindow+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIWindow+.swift"; sourceTree = ""; }; @@ -348,9 +365,6 @@ C0DF03542A5A9BD60037F740 /* ArticleListByCategoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleListByCategoryView.swift; sourceTree = ""; }; C0DF03582A5A9BF80037F740 /* ArticleCategoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleCategoryViewController.swift; sourceTree = ""; }; C0DF035A2A5A9C040037F740 /* ArticleCategoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleCategoryView.swift; sourceTree = ""; }; - C0DF035C2A5A9C260037F740 /* ArticleListByWeekTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleListByWeekTableViewCell.swift; sourceTree = ""; }; - C0DF035E2A5A9C330037F740 /* ArticleListByWeekViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleListByWeekViewController.swift; sourceTree = ""; }; - C0DF03602A5A9C400037F740 /* ArticleListByWeekView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleListByWeekView.swift; sourceTree = ""; }; C0DF03642A5A9C610037F740 /* ArticleDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleDetailView.swift; sourceTree = ""; }; C0DF03662A5A9C680037F740 /* ArticleDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleDetailViewController.swift; sourceTree = ""; }; C0DF036A2A5A9C930037F740 /* BookMarkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookMarkView.swift; sourceTree = ""; }; @@ -392,7 +406,6 @@ C0F62FE62A691FC40003ADFA /* LHLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LHLoadingView.swift; sourceTree = ""; }; D34280762A66B90C00DA1499 /* UILabelPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILabelPadding.swift; sourceTree = ""; }; D34280792A67F12200DA1499 /* ChallengeDataResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeDataResponse.swift; sourceTree = ""; }; - D342807B2A67FE4700DA1499 /* ChallengeService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeService.swift; sourceTree = ""; }; D35272D02A681E13002D7FCB /* ChallengeData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChallengeData.swift; sourceTree = ""; }; D3AB54B52A625A7B0017BF53 /* ArticleListByCategoryHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleListByCategoryHeaderView.swift; sourceTree = ""; }; D3AB54C02A62CE3F0017BF53 /* ChallengeDayCheckCollectionViewCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChallengeDayCheckCollectionViewCollectionViewCell.swift; sourceTree = ""; }; @@ -414,7 +427,6 @@ F4490C062A5CEEA300A6D9D7 /* CurriculumDummyData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumDummyData.swift; sourceTree = ""; }; F46522FC2A6048650083FBB2 /* CurriculumImagesByWeek.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumImagesByWeek.swift; sourceTree = ""; }; F47329E02A66F5D0001605D4 /* CurriculumResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumResponse.swift; sourceTree = ""; }; - F4C60E1C2A66B4CE006BBADE /* CurriculumViewService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumViewService.swift; sourceTree = ""; }; F4DB30AD2A611C7B00413EB9 /* CurriculumListByWeekViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumListByWeekViewController.swift; sourceTree = ""; }; F4DB30AF2A611C9700413EB9 /* CurriculumListByWeekData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumListByWeekData.swift; sourceTree = ""; }; F4DB30B32A61250500413EB9 /* CurriculumListByWeekCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurriculumListByWeekCollectionViewCell.swift; sourceTree = ""; }; @@ -598,9 +610,9 @@ B532E8612A55260C00F0DB19 /* Network */ = { isa = PBXGroup; children = ( - C0903D002AAAD8600014786F /* API */, + C0856B662ABFB8DB0026D9F8 /* Service */, + C0856B632ABFB84E0026D9F8 /* Manager */, B5C6A2C32A5EF4AC0021BE5E /* DTO */, - B59893172A5D41E300CE1FEB /* Services */, B532E8662A5529F700F0DB19 /* Base */, ); path = Network; @@ -827,7 +839,6 @@ children = ( B598920C2A56B3B700CE1FEB /* ArticleListByCategory */, B59892102A56B47C00CE1FEB /* ArticleCategory */, - B598920D2A56B3E900CE1FEB /* ArticleListByWeek */, B598920B2A56B3A300CE1FEB /* ArticleDetail */, ); path = Article; @@ -854,16 +865,6 @@ path = ArticleListByCategory; sourceTree = ""; }; - B598920D2A56B3E900CE1FEB /* ArticleListByWeek */ = { - isa = PBXGroup; - children = ( - B59892282A56B6AF00CE1FEB /* Cells */, - B59892272A56B6AA00CE1FEB /* ViewControllers */, - B59892262A56B6A500CE1FEB /* Views */, - ); - path = ArticleListByWeek; - sourceTree = ""; - }; B598920E2A56B41500CE1FEB /* MyPage */ = { isa = PBXGroup; children = ( @@ -938,30 +939,6 @@ path = ViewControllers; sourceTree = ""; }; - B59892262A56B6A500CE1FEB /* Views */ = { - isa = PBXGroup; - children = ( - C0DF03602A5A9C400037F740 /* ArticleListByWeekView.swift */, - ); - path = Views; - sourceTree = ""; - }; - B59892272A56B6AA00CE1FEB /* ViewControllers */ = { - isa = PBXGroup; - children = ( - C0DF035E2A5A9C330037F740 /* ArticleListByWeekViewController.swift */, - ); - path = ViewControllers; - sourceTree = ""; - }; - B59892282A56B6AF00CE1FEB /* Cells */ = { - isa = PBXGroup; - children = ( - C0DF035C2A5A9C260037F740 /* ArticleListByWeekTableViewCell.swift */, - ); - path = Cells; - sourceTree = ""; - }; B59892292A56B6BA00CE1FEB /* ViewControllers */ = { isa = PBXGroup; children = ( @@ -1113,6 +1090,7 @@ children = ( B59892E72A5B14FE00CE1FEB /* NavigationBarType.swift */, C06E38222A65353F00B00600 /* LoginType.swift */, + C0856B882ABFDA240026D9F8 /* Badge.swift */, ); path = Enums; sourceTree = ""; @@ -1129,19 +1107,6 @@ path = Font; sourceTree = ""; }; - B59893172A5D41E300CE1FEB /* Services */ = { - isa = PBXGroup; - children = ( - B59893182A5D41F600CE1FEB /* KingfisherService.swift */, - D342807B2A67FE4700DA1499 /* ChallengeService.swift */, - F4C60E1C2A66B4CE006BBADE /* CurriculumViewService.swift */, - 4AE19A162A65864F00C1DB7E /* BookmarkService.swift */, - C06E38292A662E3700B00600 /* ArticleService.swift */, - B57FEE2B2AA904D800ED6299 /* AuthMyPageServiceWrapper.swift */, - ); - path = Services; - sourceTree = ""; - }; B5C6A2C32A5EF4AC0021BE5E /* DTO */ = { isa = PBXGroup; children = ( @@ -1248,14 +1213,35 @@ path = Model; sourceTree = ""; }; - C0903D002AAAD8600014786F /* API */ = { + C0856B632ABFB84E0026D9F8 /* Manager */ = { + isa = PBXGroup; + children = ( + C0856B642ABFB8640026D9F8 /* TodayManagerImpl.swift */, + C0856B6A2ABFBC9D0026D9F8 /* ArticleDetailManagerImpl.swift */, + C0856B702ABFC0FB0026D9F8 /* ChallengeManagerImpl.swift */, + C0856B722ABFC3070026D9F8 /* BookmarkMangerImpl.swift */, + C0856B742ABFC4CB0026D9F8 /* MyPageManagerImpl.swift */, + C0856B7A2ABFC9640026D9F8 /* SplashManagerImpl.swift */, + C0856B7C2ABFCA330026D9F8 /* LoginMangerImpl.swift */, + C0856B7E2ABFCBF20026D9F8 /* ArticleListByCategoryMangerImpl.swift */, + C0856B802ABFCD830026D9F8 /* OnboardingManagerImpl.swift */, + C0856B842ABFD0F50026D9F8 /* CurriculumManagerImpl.swift */, + C0856B862ABFD24E0026D9F8 /* CurriculumListManagerImpl.swift */, + ); + path = Manager; + sourceTree = ""; + }; + C0856B662ABFB8DB0026D9F8 /* Service */ = { isa = PBXGroup; children = ( - C0903D012AAAD86A0014786F /* AuthAPI.swift */, - C004D4982AAD8F880087F044 /* MyPageAPI.swift */, - 4AD6A34B2AB1AB6700977224 /* BookmarkAPI.swift */, + C0856B682ABFB9140026D9F8 /* ArticleServiceImpl.swift */, + C0856B6C2ABFBD840026D9F8 /* BookmarkServiceImpl.swift */, + C0856B6E2ABFBFF00026D9F8 /* ChallengeServiceImpl.swift */, + C0856B762ABFC4EA0026D9F8 /* MyPageServiceImpl.swift */, + C0856B782ABFC56E0026D9F8 /* AuthServiceImpl.swift */, + C0856B822ABFCFBE0026D9F8 /* CurriculumServiceImpl.swift */, ); - path = API; + path = Service; sourceTree = ""; }; C09217652A605DEE00231C66 /* OnboardingTextFieldResultType */ = { @@ -1585,17 +1571,17 @@ C0DF03852A5AF7B70037F740 /* ChallengeViewController.swift in Sources */, C09217692A605DEE00231C66 /* OnboardingPregnancyTextFieldResultType.swift in Sources */, C0DF03A62A5CB8610037F740 /* CompleteOnbardingViewController.swift in Sources */, - D342807C2A67FE4700DA1499 /* ChallengeService.swift in Sources */, C0DF034B2A5A9B6A0037F740 /* CurriculumViewController.swift in Sources */, F435E0542A5E67BF0098E691 /* NSObject+.swift in Sources */, 4AE19A1F2A66F2E200C1DB7E /* BookmarkDetailCollectionViewCell.swift in Sources */, D3AB54B62A625A7B0017BF53 /* ArticleListByCategoryHeaderView.swift in Sources */, - B57FEE2C2AA904D800ED6299 /* AuthMyPageServiceWrapper.swift in Sources */, B59892E82A5B14FE00CE1FEB /* NavigationBarType.swift in Sources */, B57BEB6E2A6275D600D1727C /* Serviceable.swift in Sources */, D342807A2A67F12200DA1499 /* ChallengeDataResponse.swift in Sources */, B57BEB652A6134B800D1727C /* setRootViewController.swift in Sources */, + C0856B892ABFDA240026D9F8 /* Badge.swift in Sources */, B5C6A2C22A5DEA1B0021BE5E /* CopyRightTableViewCell.swift in Sources */, + C0856B7B2ABFC9640026D9F8 /* SplashManagerImpl.swift in Sources */, B59892E52A5B109900CE1FEB /* ScreenUtils.swift in Sources */, C0F029E82A5FB9EF00E0D185 /* RoundContainerView.swift in Sources */, B532E8652A5529F100F0DB19 /* BaseResponse.swift in Sources */, @@ -1603,14 +1589,12 @@ C0DF03452A5A9A910037F740 /* CurriculumTableViewCell.swift in Sources */, C07CB81E2A62C5B1000198CC /* TodayArticleView.swift in Sources */, F4490C072A5CEEA300A6D9D7 /* CurriculumDummyData.swift in Sources */, - C004D4992AAD8F880087F044 /* MyPageAPI.swift in Sources */, F4DB30AE2A611C7C00413EB9 /* CurriculumListByWeekViewController.swift in Sources */, B59892EC2A5B94E100CE1FEB /* UIApplication+.swift in Sources */, - 4AE19A172A65864F00C1DB7E /* BookmarkService.swift in Sources */, + C0856B652ABFB8640026D9F8 /* TodayManagerImpl.swift in Sources */, 4AE19A1A2A65886100C1DB7E /* BookmarkReponse.swift in Sources */, B5F323E92A6A8F0000047869 /* CurriculumWeekBackgroundDummy.swift in Sources */, C0DF039F2A5CABC10037F740 /* GetPregnancyViewController.swift in Sources */, - C0DF035F2A5A9C330037F740 /* ArticleListByWeekViewController.swift in Sources */, F4DB30BC2A61691F00413EB9 /* CurriculumArticleByWeekRowZeroTableViewCell.swift in Sources */, C0DF039A2A5B908E0037F740 /* CGColor+.swift in Sources */, 4AD216402A69AC1E00C9F2F2 /* MyPageResponse.swift in Sources */, @@ -1620,7 +1604,6 @@ B512205A2A5FAA47006CBE2D /* ImageLiterals.swift in Sources */, B57BEB612A60E97100D1727C /* NetworkErrorCode.swift in Sources */, C07CB81A2A62C54D000198CC /* TodayModel.swift in Sources */, - C0903D022AAAD86A0014786F /* AuthAPI.swift in Sources */, C06E38212A65351600B00600 /* SignUpRequest.swift in Sources */, C09A33232A62D46300B40770 /* LHToastView.swift in Sources */, B532E8632A5529B000F0DB19 /* HTTPHeaderField.swift in Sources */, @@ -1629,23 +1612,24 @@ C0DF037D2A5A9CFD0037F740 /* LoginViewController.swift in Sources */, C0DF03A42A5CACF00037F740 /* OnboardingPageType.swift in Sources */, C09A33242A630A6400B40770 /* BookmarkViewController.swift in Sources */, - C06E382A2A662E3700B00600 /* ArticleService.swift in Sources */, C0DF03352A5A93530037F740 /* UIControl+.swift in Sources */, C0F029E22A5FAE2700E0D185 /* LHOnboardingErrorLabel.swift in Sources */, B57BEB702A6275F500D1727C /* ViewControllerServiceable.swift in Sources */, - 4AD6A34C2AB1AB6700977224 /* BookmarkAPI.swift in Sources */, C0DF032F2A5A92170037F740 /* NameSpace.swift in Sources */, - B59893192A5D41F600CE1FEB /* KingfisherService.swift in Sources */, + C0856B6D2ABFBD840026D9F8 /* BookmarkServiceImpl.swift in Sources */, B59892EE2A5B9AF300CE1FEB /* NavigationBarLayoutManager.swift in Sources */, C0DF032D2A5A91D90037F740 /* DataTypeProtocol.swift in Sources */, + C0856B832ABFCFBE0026D9F8 /* CurriculumServiceImpl.swift in Sources */, C0DF03372A5A93680037F740 /* CALayer+.swift in Sources */, C0DF03A12A5CAC220037F740 /* GetFetalNicknameViewController.swift in Sources */, + C0856B852ABFD0F50026D9F8 /* CurriculumManagerImpl.swift in Sources */, C0F029EA2A5FD32900E0D185 /* LHRoundButton.swift in Sources */, C0DF03812A5AF51C0037F740 /* Constant.swift in Sources */, B59892942A57A93300CE1FEB /* Config.swift in Sources */, 4AD6AE1A2A68436B00A3D745 /* ArticleListByCategoryResponse.swift in Sources */, 4A8980D02A61850500746C58 /* MyPageAppSettingCollectionViewCell.swift in Sources */, C06E38232A65353F00B00600 /* LoginType.swift in Sources */, + C0856B6B2ABFBC9D0026D9F8 /* ArticleDetailManagerImpl.swift in Sources */, B5C6A2B62A5DD5FE0021BE5E /* TitleTableViewCell.swift in Sources */, C0DF03962A5B8FB10037F740 /* Palette.swift in Sources */, 4A3D72872A5D405C00A36189 /* BookmarkListCollectionViewCell.swift in Sources */, @@ -1656,19 +1640,23 @@ C0F029D12A5FA87900E0D185 /* Float+.swift in Sources */, C0DF036B2A5A9C930037F740 /* BookMarkView.swift in Sources */, B532E86C2A5564DD00F0DB19 /* Encodable+.swift in Sources */, - C0DF03612A5A9C400037F740 /* ArticleListByWeekView.swift in Sources */, C0DF032B2A5A918F0037F740 /* TableViewCellRegisterDequeueProtocol.swift in Sources */, B51220642A6039AA006CBE2D /* HttpMethod.swift in Sources */, B532E8322A5525C600F0DB19 /* AppDelegate.swift in Sources */, + C0856B872ABFD24E0026D9F8 /* CurriculumListManagerImpl.swift in Sources */, C0F029DE2A5FAC6100E0D185 /* LHOnboardingTitleLabel.swift in Sources */, + C0856B7D2ABFCA330026D9F8 /* LoginMangerImpl.swift in Sources */, F435E04C2A5DA6A40098E691 /* CurriculumUserInfoView.swift in Sources */, 4A8980C72A6146DA00746C58 /* MyPageCustomerServiceCollectionViewCell.swift in Sources */, + C0856B752ABFC4CB0026D9F8 /* MyPageManagerImpl.swift in Sources */, C0DF03752A5A9CD00037F740 /* TabBarViewController.swift in Sources */, C0DF035B2A5A9C040037F740 /* ArticleCategoryView.swift in Sources */, C0DF03532A5A9BC80037F740 /* ArticleListByCategoryViewController.swift in Sources */, + C0856B812ABFCD830026D9F8 /* OnboardingManagerImpl.swift in Sources */, B57BEB6C2A6149AD00D1727C /* NetworkRequest.swift in Sources */, C0DF03552A5A9BD60037F740 /* ArticleListByCategoryView.swift in Sources */, F4DB30B42A61250500413EB9 /* CurriculumListByWeekCollectionViewCell.swift in Sources */, + C0856B692ABFB9140026D9F8 /* ArticleServiceImpl.swift in Sources */, F46522FD2A6048660083FBB2 /* CurriculumImagesByWeek.swift in Sources */, 4A8980CA2A614F8700746C58 /* MyPageModel.swift in Sources */, C0DF03512A5A9BBE0037F740 /* ArticleListByCategoryTableViewCell.swift in Sources */, @@ -1680,29 +1668,32 @@ C0DF034D2A5A9B8D0037F740 /* (null) in Sources */, C09A33222A62D46300B40770 /* LHToast.swift in Sources */, B53BA2022A68717B006F9BFB /* LoadingIndicator.swift in Sources */, + C0856B7F2ABFCBF20026D9F8 /* ArticleListByCategoryMangerImpl.swift in Sources */, C06E381B2A65346700B00600 /* UserDefaultToken.swift in Sources */, + C0856B6F2ABFBFF00026D9F8 /* ChallengeServiceImpl.swift in Sources */, B5C6A2B82A5DDDFD0021BE5E /* EditorTableViewCell.swift in Sources */, C0F029C72A5EFB9D00E0D185 /* LHProgressView.swift in Sources */, B5C6A2BA2A5DE14E0021BE5E /* ChapterTitleTableViewCell.swift in Sources */, C0DF034D2A5A9B8D0037F740 /* (null) in Sources */, + C0856B772ABFC4EA0026D9F8 /* MyPageServiceImpl.swift in Sources */, C0DF03982A5B90790037F740 /* UIColor+.swift in Sources */, C0F029E02A5FAD1200E0D185 /* LHOnboardingDescriptionLabel.swift in Sources */, C0DF03492A5A9ACB0037F740 /* DummyModel.swift in Sources */, + C0856B792ABFC56E0026D9F8 /* AuthServiceImpl.swift in Sources */, C09217732A61895A00231C66 /* UIWindow+.swift in Sources */, D3BA0B712A5CFA2300B6361F /* ArticleCategoryCollectionViewCell.swift in Sources */, B532E8342A5525C600F0DB19 /* SceneDelegate.swift in Sources */, C0F029CD2A5F8D2F00E0D185 /* UIPageViewController+.swift in Sources */, + C0856B732ABFC3070026D9F8 /* BookmarkMangerImpl.swift in Sources */, B57BEB632A612DA100D1727C /* UserDefaultsManager.swift in Sources */, C0DF037B2A5A9CF30037F740 /* OnboardingViewController.swift in Sources */, C09217682A605DEE00231C66 /* OnboardingFetalNicknameTextFieldResultType.swift in Sources */, C0F62FCA2A67CDCE0003ADFA /* BookmarkDetailCollectionViewCell.swift in Sources */, - C0DF035D2A5A9C260037F740 /* ArticleListByWeekTableViewCell.swift in Sources */, C0DF03592A5A9BF80037F740 /* ArticleCategoryViewController.swift in Sources */, C00780BA2A60149D0043EB36 /* LHTodayArticleTitle.swift in Sources */, B51220602A60111C006CBE2D /* Token.swift in Sources */, B5C6A2C82A5EF4EB0021BE5E /* ArticleDetail.swift in Sources */, C0DF03312A5A92730037F740 /* CollectionViewCellRegisterDequeueProtocol.swift in Sources */, - F4C60E1D2A66B4CE006BBADE /* CurriculumViewService.swift in Sources */, C06E381D2A65348A00B00600 /* LoginRequest.swift in Sources */, C0DF033D2A5A95420037F740 /* UIStackView+.swift in Sources */, 4A8980CC2A61795500746C58 /* MyPageHeaderView.swift in Sources */, @@ -1718,6 +1709,7 @@ B5C6A2B22A5DB0B10021BE5E /* ArticleDetailTableView.swift in Sources */, B59892E12A5AF39300CE1FEB /* LHNavigationBarView.swift in Sources */, C0F029E62A5FB9E000E0D185 /* ContainerView.swift in Sources */, + C0856B712ABFC0FB0026D9F8 /* ChallengeManagerImpl.swift in Sources */, C0DF03672A5A9C680037F740 /* ArticleDetailViewController.swift in Sources */, 4AE19A1E2A6597E700C1DB7E /* BookmarkRequest.swift in Sources */, ); diff --git a/LionHeart-iOS/LionHeart-iOS/Application/SceneDelegate.swift b/LionHeart-iOS/LionHeart-iOS/Application/SceneDelegate.swift index 9fcd8bef..50df2174 100644 --- a/LionHeart-iOS/LionHeart-iOS/Application/SceneDelegate.swift +++ b/LionHeart-iOS/LionHeart-iOS/Application/SceneDelegate.swift @@ -31,7 +31,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { self.window = UIWindow(windowScene: windowScene) /// 폰트등록 Font.registerFonts() - let navigationController = UINavigationController(rootViewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService())))) + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + let navigationController = UINavigationController(rootViewController: splashViewController) self.window?.rootViewController = navigationController self.window?.makeKeyAndVisible() } diff --git a/LionHeart-iOS/LionHeart-iOS/Global/Enums/Badge.swift b/LionHeart-iOS/LionHeart-iOS/Global/Enums/Badge.swift new file mode 100644 index 00000000..5be6a3c4 --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Global/Enums/Badge.swift @@ -0,0 +1,46 @@ +// +// Badge.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import UIKit + +enum BadgeLevel: String { + case level01 = "LEVEL_ONE" + case level02 = "LEVEL_TWO" + case level03 = "LEVEL_THREE" + case level04 = "LEVEL_FOUR" + case level05 = "LEVEL_FIVE" + + var badgeLevel: Int { + switch self { + case .level01: return 1 + case .level02: return 2 + case .level03: return 3 + case .level04: return 4 + case .level05: return 5 + } + } + + var badgeImage: UIImage { + switch self { + case .level01: return ImageLiterals.ChallengeBadge.level01 + case .level02: return ImageLiterals.ChallengeBadge.level02 + case .level03: return ImageLiterals.ChallengeBadge.level03 + case .level04: return ImageLiterals.ChallengeBadge.level04 + case .level05: return ImageLiterals.ChallengeBadge.level05 + } + } + + var progreddbarLottie: String { + switch self { + case .level01: return "Level1" + case .level02: return "Level2" + case .level03: return "Level3" + case .level04: return "Level4" + case .level05: return "Level5" + } + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Global/Extensions/UIViewController+.swift b/LionHeart-iOS/LionHeart-iOS/Global/Extensions/UIViewController+.swift index 68dc9806..cd5e089c 100644 --- a/LionHeart-iOS/LionHeart-iOS/Global/Extensions/UIViewController+.swift +++ b/LionHeart-iOS/LionHeart-iOS/Global/Extensions/UIViewController+.swift @@ -89,7 +89,7 @@ extension UIViewController { extension UIViewController { func presentArticleDetailFullScreen(articleID: Int) { - let articleDetailViewController = ArticleDetailViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) + let articleDetailViewController = ArticleDetailViewController(manager: ArticleDetailManagerImpl(articleService: ArticleServiceImpl(apiService: APIService()), bookmarkService: BookmarkServiceImpl(apiService: APIService()))) articleDetailViewController.setArticleId(id: articleID) articleDetailViewController.isModalInPresentation = true articleDetailViewController.modalPresentationStyle = .fullScreen diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Base/APIService.swift b/LionHeart-iOS/LionHeart-iOS/Network/Base/APIService.swift index 970d53bf..92092d86 100644 --- a/LionHeart-iOS/LionHeart-iOS/Network/Base/APIService.swift +++ b/LionHeart-iOS/LionHeart-iOS/Network/Base/APIService.swift @@ -28,7 +28,7 @@ final class APIService: Requestable { throw NetworkError.serverError } - print("✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅APIService성공✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅") + print("✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅API호출성공✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅") return decodedData.data } } diff --git a/LionHeart-iOS/LionHeart-iOS/Network/DTO/Challenge/ChallengeDataResponse.swift b/LionHeart-iOS/LionHeart-iOS/Network/DTO/Challenge/ChallengeDataResponse.swift index bd88cea5..c2a1cfb8 100644 --- a/LionHeart-iOS/LionHeart-iOS/Network/DTO/Challenge/ChallengeDataResponse.swift +++ b/LionHeart-iOS/LionHeart-iOS/Network/DTO/Challenge/ChallengeDataResponse.swift @@ -13,3 +13,9 @@ struct ChallengeDataResponse: DTO, Response { let level: String let attendances: [String] } + +extension ChallengeDataResponse { + func toAppData() -> ChallengeData { + return .init(babyDaddyName: self.babyNickname, howLongDay: self.day, daddyLevel: self.level, daddyAttendances: self.attendances) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/DTO/Today/TodayArticleResponse.swift b/LionHeart-iOS/LionHeart-iOS/Network/DTO/Today/TodayArticleResponse.swift index db6c9555..d28edf62 100644 --- a/LionHeart-iOS/LionHeart-iOS/Network/DTO/Today/TodayArticleResponse.swift +++ b/LionHeart-iOS/LionHeart-iOS/Network/DTO/Today/TodayArticleResponse.swift @@ -16,3 +16,9 @@ struct TodayArticleResponse: DTO, Response { let day: Int let articleId: Int } + +extension TodayArticleResponse { + func toAppData() -> TodayArticle { + return .init(fetalNickname: self.babyNickname, articleTitle: self.title, articleDescription: self.editorNoteContent, currentWeek: self.week, currentDay: self.day, mainImageURL: self.mainImageUrl, aticleID: self.articleId) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/ArticleDetailManagerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/ArticleDetailManagerImpl.swift new file mode 100644 index 00000000..8548675f --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/ArticleDetailManagerImpl.swift @@ -0,0 +1,29 @@ +// +// ArticleDetailManagerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class ArticleDetailManagerImpl: ArticleDetailManager { + + private let articleService: ArticleService + private let bookmarkService: BookmarkOutService + + init(articleService: ArticleService, bookmarkService: BookmarkOutService) { + self.articleService = articleService + self.bookmarkService = bookmarkService + } + + func getArticleDetail(articleId: Int) async throws -> [BlockTypeAppData] { + guard let model = try await articleService.getArticleDetail(articleId: articleId) else { return []} + return model.toAppData() + } + + func postBookmark(model: BookmarkRequest) async throws { + guard let data = try await bookmarkService.postBookmark(model: model) else { throw NetworkError.badCasting } + print(data) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/ArticleListByCategoryMangerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/ArticleListByCategoryMangerImpl.swift new file mode 100644 index 00000000..446662bd --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/ArticleListByCategoryMangerImpl.swift @@ -0,0 +1,29 @@ +// +// ArticleListByCategoryMangerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class ArticleListByCategoryMangerImpl: ArticleListByCategoryManager { + + private let articleService: ArticleService + private let bookmarkService: BookmarkOutService + + init(articleService: ArticleService, bookmarkService: BookmarkOutService) { + self.articleService = articleService + self.bookmarkService = bookmarkService + } + + func getArticleListByCategory(categoryString: String) async throws -> CurriculumWeekData { + guard let model = try await articleService.getArticleListByCategory(categoryString: categoryString) else { throw NetworkError.badCasting } + return model.toAppData() + } + + func postBookmark(model: BookmarkRequest) async throws { + guard let data = try await bookmarkService.postBookmark(model: model) else { throw NetworkError.badCasting } + print(data) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/BookmarkMangerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/BookmarkMangerImpl.swift new file mode 100644 index 00000000..b301afdd --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/BookmarkMangerImpl.swift @@ -0,0 +1,27 @@ +// +// BookmarkMangerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class BookmarkMangerImpl: BookmarkManger { + + private let bookmarkService: BookmarkService + + init(bookmarkService: BookmarkService) { + self.bookmarkService = bookmarkService + } + + func getBookmark() async throws -> BookmarkAppData { + guard let model = try await bookmarkService.getBookmark() else { return .empty } + return model.toAppData() + } + + func postBookmark(model: BookmarkRequest) async throws { + guard let data = try await bookmarkService.postBookmark(model: model) else { throw NetworkError.badCasting } + print(data) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/ChallengeManagerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/ChallengeManagerImpl.swift new file mode 100644 index 00000000..4281c39d --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/ChallengeManagerImpl.swift @@ -0,0 +1,22 @@ +// +// ChallengeManagerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class ChallengeManagerImpl: ChallengeManager { + + private let challengeService: ChallengeService + + init(challengeService: ChallengeService) { + self.challengeService = challengeService + } + + func inquireChallengeInfo() async throws -> ChallengeData { + guard let model = try await challengeService.inquireChallengeInfo() else { return .empty } + return model.toAppData() + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/CurriculumListManagerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/CurriculumListManagerImpl.swift new file mode 100644 index 00000000..589e084c --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/CurriculumListManagerImpl.swift @@ -0,0 +1,29 @@ +// +// CurriculumListManagerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class CurriculumListManagerImpl: CurriculumListManager { + + private let bookmarkService: BookmarkOutService + private let curriculumService: CurriculumService + + init(bookmarkService: BookmarkOutService, curriculumService: CurriculumService) { + self.bookmarkService = bookmarkService + self.curriculumService = curriculumService + } + + func postBookmark(model: BookmarkRequest) async throws { + guard let data = try await bookmarkService.postBookmark(model: model) else { throw NetworkError.badCasting } + print(data) + } + + func getArticleListByWeekInfo(week: Int) async throws -> CurriculumWeekData { + guard let model = try await curriculumService.getArticleListByWeekInfo(week: week) else { throw NetworkError.badCasting } + return model.toAppData() + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/CurriculumManagerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/CurriculumManagerImpl.swift new file mode 100644 index 00000000..7041210a --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/CurriculumManagerImpl.swift @@ -0,0 +1,22 @@ +// +// CurriculumManagerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class CurriculumManagerImpl: CurriculumManager { + + private let curriculumService: CurriculumService + + init(curriculumService: CurriculumService) { + self.curriculumService = curriculumService + } + + func getCurriculumServiceInfo() async throws -> UserInfoData { + guard let model = try await curriculumService.getCurriculumServiceInfo() else { throw NetworkError.badCasting } + return UserInfoData(userWeekInfo: model.week, userDayInfo: model.day, progress: model.progress + 1, remainingDay: model.remainingDay) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/LoginMangerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/LoginMangerImpl.swift new file mode 100644 index 00000000..2c70db34 --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/LoginMangerImpl.swift @@ -0,0 +1,21 @@ +// +// LoginMangerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class LoginMangerImpl: LoginManager { + + private let authService: AuthUserInService + + init(authService: AuthUserInService) { + self.authService = authService + } + + func login(type: LoginType, kakaoToken: String) async throws { + try await authService.login(type: type, kakaoToken: kakaoToken) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/MyPageManagerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/MyPageManagerImpl.swift new file mode 100644 index 00000000..d3fc9680 --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/MyPageManagerImpl.swift @@ -0,0 +1,32 @@ +// +// MyPageManagerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class MyPageManagerImpl: MyPageManager { + + private let mypageService: MypageService + private let authService: AuthUserOutService + + init(mypageService: MypageService, authService: AuthUserOutService) { + self.mypageService = mypageService + self.authService = authService + } + + func getMyPage() async throws -> MyPageAppData { + guard let model = try await mypageService.getMyPage() else { throw NetworkError.badCasting } + return MyPageAppData(badgeImage: model.level, nickname: model.babyNickname, isAlarm: model.notificationStatus) + } + + func resignUser() async throws { + try await authService.resignUser() + } + + func logout(token: UserDefaultToken) async throws { + try await authService.logout(token: token) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/OnboardingManagerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/OnboardingManagerImpl.swift new file mode 100644 index 00000000..5a51d44a --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/OnboardingManagerImpl.swift @@ -0,0 +1,21 @@ +// +// OnboardingManagerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class OnboardingManagerImpl: OnboardingManager { + + private let authService: AuthUserInService + + init(authService: AuthUserInService) { + self.authService = authService + } + + func signUp(type: LoginType, onboardingModel: UserOnboardingModel) async throws { + try await authService.signUp(type: type, onboardingModel: onboardingModel) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/SplashManagerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/SplashManagerImpl.swift new file mode 100644 index 00000000..c4aac6da --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/SplashManagerImpl.swift @@ -0,0 +1,25 @@ +// +// SplashManagerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class SplashManagerImpl: SplashManager { + + private let authService: AuthService + + init(authService: AuthService) { + self.authService = authService + } + + func reissueToken(token: Token) async throws -> Token? { + return try await authService.reissueToken(token: token) + } + + func logout(token: UserDefaultToken) async throws { + try await authService.logout(token: token) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Manager/TodayManagerImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Manager/TodayManagerImpl.swift new file mode 100644 index 00000000..5948ed42 --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Manager/TodayManagerImpl.swift @@ -0,0 +1,22 @@ +// +// TodayManagerImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +final class TodayManagerImpl: TodayManager { + + private let articleService: ArticleService + + init(articleService: ArticleService) { + self.articleService = articleService + } + + func inquiryTodayArticle() async throws -> TodayArticle { + guard let model = try await articleService.inquiryTodayArticle() else { return .emptyArticle } + return model.toAppData() + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Service/ArticleServiceImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Service/ArticleServiceImpl.swift new file mode 100644 index 00000000..ce79e8af --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Service/ArticleServiceImpl.swift @@ -0,0 +1,43 @@ +// +// ArticleServiceImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +struct Query: Request { + let category: String +} + +protocol ArticleService { + func inquiryTodayArticle() async throws -> TodayArticleResponse? + func getArticleDetail(articleId: Int) async throws -> ArticleDetail? + func getArticleListByCategory(categoryString: String) async throws -> CategoryList? +} + +final class ArticleServiceImpl: ArticleService { + + private let apiService: Requestable + + init(apiService: Requestable) { + self.apiService = apiService + } + + func inquiryTodayArticle() async throws -> TodayArticleResponse? { + let urlRequest = try NetworkRequest(path: "/v1/article/today", httpMethod: .get).makeURLRequest(isLogined: true) + return try await apiService.request(urlRequest) + } + + func getArticleDetail(articleId: Int) async throws -> ArticleDetail? { + let urlRequest = try NetworkRequest(path: "/v1/article/\(articleId)", httpMethod: .get).makeURLRequest(isLogined: true) + return try await apiService.request(urlRequest) + } + + func getArticleListByCategory(categoryString: String) async throws -> CategoryList? { + let query = Query(category: categoryString) + let urlRequest = try NetworkRequest(path: "/v1/article", httpMethod: .get, query: query).makeURLRequest(isLogined: true) + return try await apiService.request(urlRequest) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/API/AuthAPI.swift b/LionHeart-iOS/LionHeart-iOS/Network/Service/AuthServiceImpl.swift similarity index 92% rename from LionHeart-iOS/LionHeart-iOS/Network/API/AuthAPI.swift rename to LionHeart-iOS/LionHeart-iOS/Network/Service/AuthServiceImpl.swift index 7f04ebb9..1c4e2846 100644 --- a/LionHeart-iOS/LionHeart-iOS/Network/API/AuthAPI.swift +++ b/LionHeart-iOS/LionHeart-iOS/Network/Service/AuthServiceImpl.swift @@ -1,21 +1,28 @@ // -// AuthAPI.swift +// AuthServiceImpl.swift // LionHeart-iOS // -// Created by uiskim on 2023/09/08. +// Created by uiskim on 2023/09/24. // import Foundation -protocol AuthAPIProtocol { +import Foundation + +protocol AuthUserInService { func reissueToken(token: Token) async throws -> Token? func login(type: LoginType, kakaoToken: String) async throws func signUp(type: LoginType, onboardingModel: UserOnboardingModel) async throws +} + +protocol AuthUserOutService { @discardableResult func logout(token: UserDefaultToken) async throws -> String? func resignUser() async throws } -final class AuthAPI: AuthAPIProtocol { +typealias AuthService = AuthUserInService & AuthUserOutService + +final class AuthServiceImpl: AuthService { private let apiService: Requestable @@ -50,14 +57,14 @@ final class AuthAPI: AuthAPIProtocol { } } -extension AuthAPI { +extension AuthServiceImpl { private func userdefaultsSettingWhenUserIn(model: Token?) { UserDefaultsManager.tokenKey?.accessToken = model?.accessToken UserDefaultsManager.tokenKey?.refreshToken = model?.refreshToken } } -extension AuthAPI { +extension AuthServiceImpl { func makeResignUserUrlRequest() throws -> URLRequest { return try NetworkRequest(path: "/v1/member", httpMethod: .delete).makeURLRequest(isLogined: true) } diff --git a/LionHeart-iOS/LionHeart-iOS/Network/API/BookmarkAPI.swift b/LionHeart-iOS/LionHeart-iOS/Network/Service/BookmarkServiceImpl.swift similarity index 77% rename from LionHeart-iOS/LionHeart-iOS/Network/API/BookmarkAPI.swift rename to LionHeart-iOS/LionHeart-iOS/Network/Service/BookmarkServiceImpl.swift index 8823c42b..325364bb 100644 --- a/LionHeart-iOS/LionHeart-iOS/Network/API/BookmarkAPI.swift +++ b/LionHeart-iOS/LionHeart-iOS/Network/Service/BookmarkServiceImpl.swift @@ -1,18 +1,24 @@ // -// BookmarkAPI.swift +// BookmarkServiceImpl.swift // LionHeart-iOS // -// Created by 황찬미 on 2023/09/13. +// Created by uiskim on 2023/09/24. // import Foundation -protocol BookmarkAPIProtocol { +protocol BookmarkInOutService { func getBookmark() async throws -> BookmarkResponse? func postBookmark(model: BookmarkRequest) async throws -> BookmarkResponse? } -final class BookmarkAPI: BookmarkAPIProtocol { +protocol BookmarkOutService { + func postBookmark(model: BookmarkRequest) async throws -> BookmarkResponse? +} + +typealias BookmarkService = BookmarkInOutService & BookmarkOutService + +final class BookmarkServiceImpl: BookmarkService { private let apiService: Requestable @@ -31,9 +37,7 @@ final class BookmarkAPI: BookmarkAPIProtocol { } } - -/// url request method -extension BookmarkAPI { +extension BookmarkServiceImpl { func makeGetBookmarkUrlRequest() throws -> URLRequest { return try NetworkRequest(path: "/v1/article/bookmarks", httpMethod: .get).makeURLRequest(isLogined: true) } @@ -41,7 +45,6 @@ extension BookmarkAPI { func makePostBookmakrUrlRequest(model: BookmarkRequest) throws -> URLRequest { let param = model.toDictionary() let body = try JSONSerialization.data(withJSONObject: param) - return try NetworkRequest(path: "/v1/article/bookmark", httpMethod: .post, body: body).makeURLRequest(isLogined: true) } } diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Service/ChallengeServiceImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Service/ChallengeServiceImpl.swift new file mode 100644 index 00000000..c5477bab --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Service/ChallengeServiceImpl.swift @@ -0,0 +1,26 @@ +// +// ChallengeServiceImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +protocol ChallengeService { + func inquireChallengeInfo() async throws -> ChallengeDataResponse? +} + +final class ChallengeServiceImpl: ChallengeService { + + private let apiService: Requestable + + init(apiService: Requestable) { + self.apiService = apiService + } + + func inquireChallengeInfo() async throws -> ChallengeDataResponse? { + let urlRequest = try NetworkRequest(path: "/v1/challenge/progress", httpMethod: .get).makeURLRequest(isLogined: true) + return try await apiService.request(urlRequest) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Service/CurriculumServiceImpl.swift b/LionHeart-iOS/LionHeart-iOS/Network/Service/CurriculumServiceImpl.swift new file mode 100644 index 00000000..cd9148e1 --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/Service/CurriculumServiceImpl.swift @@ -0,0 +1,32 @@ +// +// CurriculumServiceImpl.swift +// LionHeart-iOS +// +// Created by uiskim on 2023/09/24. +// + +import Foundation + +protocol CurriculumService { + func getArticleListByWeekInfo(week: Int) async throws -> CurriculumListByWeekResponse? + func getCurriculumServiceInfo() async throws -> CurriculumResponse? +} + +final class CurriculumServiceImpl: CurriculumService { + + private let apiService: Requestable + + init(apiService: Requestable) { + self.apiService = apiService + } + + func getArticleListByWeekInfo(week: Int) async throws -> CurriculumListByWeekResponse? { + let urlRequest = try NetworkRequest(path: "v1/article/week/\(week)", httpMethod: .get).makeURLRequest(isLogined: true) + return try await apiService.request(urlRequest) + } + + func getCurriculumServiceInfo() async throws -> CurriculumResponse? { + let urlRequest = try NetworkRequest(path: "/v1/curriculum/progress", httpMethod: .get).makeURLRequest(isLogined: true) + return try await apiService.request(urlRequest) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/API/MyPageAPI.swift b/LionHeart-iOS/LionHeart-iOS/Network/Service/MyPageServiceImpl.swift similarity index 77% rename from LionHeart-iOS/LionHeart-iOS/Network/API/MyPageAPI.swift rename to LionHeart-iOS/LionHeart-iOS/Network/Service/MyPageServiceImpl.swift index a59ee194..93bedf3f 100644 --- a/LionHeart-iOS/LionHeart-iOS/Network/API/MyPageAPI.swift +++ b/LionHeart-iOS/LionHeart-iOS/Network/Service/MyPageServiceImpl.swift @@ -1,17 +1,17 @@ // -// MyPageAPI.swift +// MyPageServiceImpl.swift // LionHeart-iOS // -// Created by uiskim on 2023/09/10. +// Created by uiskim on 2023/09/24. // import Foundation -protocol MyPageAPIProtocol { +protocol MypageService { func getMyPage() async throws -> MyPageResponse? } -final class MyPageAPI: MyPageAPIProtocol { +final class MyPageServiceImpl: MypageService { private let apiService: Requestable diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Services/ArticleService.swift b/LionHeart-iOS/LionHeart-iOS/Network/Services/ArticleService.swift deleted file mode 100644 index 60c72d86..00000000 --- a/LionHeart-iOS/LionHeart-iOS/Network/Services/ArticleService.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// ArticleService.swift -// LionHeart-iOS -// -// Created by uiskim on 2023/07/18. -// - -import UIKit - -struct Query: Request { - let category: String -} - -final class ArticleService: Serviceable { - static let shared = ArticleService() - private init() {} - - func inquiryTodayArticle() async throws -> TodayArticle { - let urlRequest = try NetworkRequest(path: "/v1/article/today", httpMethod: .get).makeURLRequest(isLogined: true) - let (data, _) = try await URLSession.shared.data(for: urlRequest) - - guard let model = try dataDecodeAndhandleErrorCode(data: data, decodeType: TodayArticleResponse.self) - else { return TodayArticle.emptyArticle } - - return .init(fetalNickname: model.babyNickname, articleTitle: model.title, articleDescription: model.editorNoteContent, currentWeek: model.week, currentDay: model.day, mainImageURL: model.mainImageUrl, aticleID: model.articleId) - } - - func getArticleDetail(articleId: Int) async throws -> [BlockTypeAppData] { - let urlRequest = try NetworkRequest(path: "/v1/article/\(articleId)", httpMethod: .get).makeURLRequest(isLogined: true) - - let (data, _) = try await URLSession.shared.data(for: urlRequest) - - guard let model = try dataDecodeAndhandleErrorCode(data: data, decodeType: ArticleDetail.self) else { - return [] - } - - return model.toAppData() - } - - func getArticleListByCategory(categoryString: String) async throws -> CurriculumWeekData { - let query = Query(category: categoryString) - - let urlRequest = try NetworkRequest(path: "/v1/article", httpMethod: .get, query: query).makeURLRequest(isLogined: true) - - let (data, _) = try await URLSession.shared.data(for: urlRequest) - - guard let model = try dataDecodeAndhandleErrorCode(data: data, decodeType: CategoryList.self) else { - return .init(articleData: [], week: nil) - } - - return model.toAppData() - } -} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Services/AuthMyPageServiceWrapper.swift b/LionHeart-iOS/LionHeart-iOS/Network/Services/AuthMyPageServiceWrapper.swift deleted file mode 100644 index 592ceb02..00000000 --- a/LionHeart-iOS/LionHeart-iOS/Network/Services/AuthMyPageServiceWrapper.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// AuthMyPageServiceWrapper.swift -// LionHeart-iOS -// -// Created by 김민재 on 2023/09/07. -// - -import Foundation - -final class AuthMyPageServiceWrapper: AuthServiceProtocol, MyPageServiceProtocol { - - private let authAPIService: AuthAPIProtocol - private let mypageAPIService: MyPageAPIProtocol - - init(authAPIService: AuthAPIProtocol, mypageAPIService: MyPageAPIProtocol) { - self.authAPIService = authAPIService - self.mypageAPIService = mypageAPIService - } - - func getMyPage() async throws -> MyPageAppData { - guard let model = try await mypageAPIService.getMyPage() - else { return MyPageAppData.empty } - return MyPageAppData(badgeImage: model.level, nickname: model.babyNickname, isAlarm: model.notificationStatus) - } - - func reissueToken(token: Token) async throws -> Token? { - let model = try await authAPIService.reissueToken(token: token) - return try await authAPIService.reissueToken(token: token) - } - - func login(type: LoginType, kakaoToken: String) async throws { - try await authAPIService.login(type: type, kakaoToken: kakaoToken) - } - - func signUp(type: LoginType, onboardingModel: UserOnboardingModel) async throws { - try await authAPIService.signUp(type: type, onboardingModel: onboardingModel) - } - - func resignUser() async throws { - try await authAPIService.resignUser() - } - - func logout(token: UserDefaultToken) async throws { - try await authAPIService.logout(token: token) - } - -} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Services/BookmarkService.swift b/LionHeart-iOS/LionHeart-iOS/Network/Services/BookmarkService.swift deleted file mode 100644 index 7817f5d5..00000000 --- a/LionHeart-iOS/LionHeart-iOS/Network/Services/BookmarkService.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// BookmarkService.swift -// LionHeart-iOS -// -// Created by 황찬미 on 2023/07/17. -// - -import Foundation - -/// 내 북마크 -protocol BookmarkInOutServiceProtocol { - func postBookmark(model: BookmarkRequest) async throws - func getBookmark() async throws -> BookmarkAppData -} - -// 동뷰, 성뷰 -protocol BookmarkOutProtocol { - func postBookmark(model: BookmarkRequest) async throws -} - -final class BookmarkService: BookmarkInOutServiceProtocol, BookmarkOutProtocol { - - private let bookmarkAPIProtocol: BookmarkAPIProtocol - - init(bookmarkAPIProtocol: BookmarkAPIProtocol) { - self.bookmarkAPIProtocol = bookmarkAPIProtocol - } - - func postBookmark(model: BookmarkRequest) async throws { - guard let data = try await bookmarkAPIProtocol.postBookmark(model: model) else { return } - print(data) - } - - func getBookmark() async throws -> BookmarkAppData { - guard let data = try await bookmarkAPIProtocol.getBookmark() else { return BookmarkAppData(nickName: "", articleSummaries: [])} - return data.toAppData() - } -} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Services/ChallengeService.swift b/LionHeart-iOS/LionHeart-iOS/Network/Services/ChallengeService.swift deleted file mode 100644 index 8d9c0edd..00000000 --- a/LionHeart-iOS/LionHeart-iOS/Network/Services/ChallengeService.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// ChallengeService.swift -// LionHeart-iOS -// -// Created by 김동현 on 2023/07/19. -// - -import Foundation - -final class ChallengeService: Serviceable { - static let shared = ChallengeService() - private init() {} - - func inquireChallengeInfo() async throws -> ChallengeData{ - let urlRequest = try NetworkRequest(path: "/v1/challenge/progress", httpMethod: .get) - .makeURLRequest(isLogined: true) - - let (data, _) = try await URLSession.shared.data(for: urlRequest) - - guard let model = try dataDecodeAndhandleErrorCode(data: data, decodeType: ChallengeDataResponse.self) else { return ChallengeData(babyDaddyName: "", howLongDay: 0, daddyLevel: "", daddyAttendances: []) } - - return ChallengeData(babyDaddyName: model.babyNickname, - howLongDay: model.day, - daddyLevel: model.level, - daddyAttendances: model.attendances) - } -} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Services/CurriculumViewService.swift b/LionHeart-iOS/LionHeart-iOS/Network/Services/CurriculumViewService.swift deleted file mode 100644 index 718c5fad..00000000 --- a/LionHeart-iOS/LionHeart-iOS/Network/Services/CurriculumViewService.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// CurriculumViewService.swift -// LionHeart-iOS -// -// Created by 곽성준 on 2023/07/18. -// - -import UIKit - -final class CurriculumService: Serviceable { - - static let shared = CurriculumService() - - private init() {} - - func getCurriculumServiceInfo() async throws -> UserInfoData { - let urlRequest = try NetworkRequest(path: "/v1/curriculum/progress", httpMethod: .get).makeURLRequest(isLogined: true) - - let (data, _) = try await URLSession.shared.data(for: urlRequest) - guard let model = try dataDecodeAndhandleErrorCode(data: data, decodeType: CurriculumResponse.self) else { return UserInfoData.emptyUserInfoData } - - return UserInfoData(userWeekInfo: model.week, userDayInfo: model.day, progress: model.progress + 1, remainingDay: model.remainingDay) - } - - func getArticleListByWeekInfo(week: Int) async throws -> CurriculumWeekData { - let urlRequest = try NetworkRequest(path: "v1/article/week/\(week)", httpMethod: .get).makeURLRequest(isLogined: true) - - let (data, _) = try await URLSession.shared.data(for: urlRequest) - guard let model = try dataDecodeAndhandleErrorCode(data: data, decodeType: CurriculumListByWeekResponse.self) else { - return .init(articleData: [], week: 0) - } - - return model.toAppData() - } -} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Services/KingfisherService.swift b/LionHeart-iOS/LionHeart-iOS/Network/Services/KingfisherService.swift deleted file mode 100644 index dc889e6e..00000000 --- a/LionHeart-iOS/LionHeart-iOS/Network/Services/KingfisherService.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -// KingfisherService.swift -// LionHeart-iOS -// -// Created by 김민재 on 2023/07/11. -// - -import UIKit - -import Kingfisher - - -final class LHKingFisherService { - - static func fetchImage(with urlString: String) async throws -> UIImage? { - typealias ImageContinuation = CheckedContinuation - - return try await withCheckedThrowingContinuation { ImageContinuation in - - guard let url = URL(string: urlString) else { - return ImageContinuation.resume(throwing: NetworkError.urlEncodingError) - } - - let resource = KF.ImageResource(downloadURL: url, cacheKey: urlString) - KingfisherManager.shared.retrieveImage(with: resource) { result in - switch result { - case .success(let imageResult): - let image = imageResult.image - return ImageContinuation.resume(returning: image) - case .failure(_): - return ImageContinuation.resume(throwing: NetworkError.fetchImageError) - } - } - } - - } - - func unwrapTaskArray(dataTasks: [Task], type: T.Type) async -> [T] { - let tasks = dataTasks.map { task in - Task { - return try await task.result.get() - } - } - - var result: [T?] = [] - for task in tasks { - result.append(try? await task.result.get()) - } - return result.compactMap { $0 } - } - -} diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleCategory/ViewControllers/ArticleCategoryViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleCategory/ViewControllers/ArticleCategoryViewController.swift index 0e23f331..52c0bfa5 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleCategory/ViewControllers/ArticleCategoryViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleCategory/ViewControllers/ArticleCategoryViewController.swift @@ -97,14 +97,13 @@ private extension ArticleCategoryViewController { func setAddTarget() { navigationBar.rightFirstBarItemAction { - let bookmarkViewController = BookmarkViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) + let bookmarkViewController = BookmarkViewController(manager: BookmarkMangerImpl(bookmarkService: BookmarkServiceImpl(apiService: APIService()))) self.navigationController?.pushViewController(bookmarkViewController, animated: true) } navigationBar.rightSecondBarItemAction { - let wrapper = AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService())) - let myPageViewController = MyPageViewController(service: wrapper) - self.navigationController?.pushViewController(myPageViewController, animated: true) + let mypageViewController = MyPageViewController(manager: MyPageManagerImpl(mypageService: MyPageServiceImpl(apiService: APIService()), authService: AuthServiceImpl(apiService: APIService()))) + self.navigationController?.pushViewController(mypageViewController, animated: true) } } @@ -134,9 +133,9 @@ extension ArticleCategoryViewController: UICollectionViewDataSource { } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - let ArticleListByCategoryVC = ArticleListByCategoryViewController(serviceProcotol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) - ArticleListByCategoryVC.categoryString = dummyCase[indexPath.item].categoryString - self.navigationController?.pushViewController(ArticleListByCategoryVC, animated: true) + let articleListbyCategoryViewController = ArticleListByCategoryViewController(manager: ArticleListByCategoryMangerImpl(articleService: ArticleServiceImpl(apiService: APIService()), bookmarkService: BookmarkServiceImpl(apiService: APIService()))) + articleListbyCategoryViewController.categoryString = dummyCase[indexPath.item].categoryString + self.navigationController?.pushViewController(articleListbyCategoryViewController, animated: true) } } diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleDetail/ViewControllers/ArticleDetailViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleDetail/ViewControllers/ArticleDetailViewController.swift index 1d63310b..41409318 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleDetail/ViewControllers/ArticleDetailViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleDetail/ViewControllers/ArticleDetailViewController.swift @@ -10,11 +10,15 @@ import UIKit import SnapKit +protocol ArticleDetailManager { + func getArticleDetail(articleId: Int) async throws -> [BlockTypeAppData] + func postBookmark(model: BookmarkRequest) async throws +} + final class ArticleDetailViewController: UIViewController { // MARK: - UI Components - - private let serviceProtocol: BookmarkOutProtocol + private let manager: ArticleDetailManager private lazy var navigationBar = LHNavigationBarView(type: .articleMain, viewController: self) @@ -33,17 +37,7 @@ final class ArticleDetailViewController: UIViewController { button.isHidden = true return button }() - - init(serviceProtocol: BookmarkOutProtocol) { - self.serviceProtocol = serviceProtocol - /// 이 코드는 왜 있어야 하지? - super.init(nibName: nil, bundle: nil) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - + // MARK: - Properties private var isBookMarked: Bool? { @@ -63,6 +57,15 @@ final class ArticleDetailViewController: UIViewController { private var articleId: Int? private var contentOffsetY: CGFloat = 0 + + init(manager: ArticleDetailManager) { + self.manager = manager + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } public override func viewDidLoad() { super.viewDidLoad() @@ -94,7 +97,7 @@ extension ArticleDetailViewController { Task { do { guard let articleId else { return } - self.articleDatas = try await ArticleService.shared.getArticleDetail(articleId: articleId) + self.articleDatas = try await manager.getArticleDetail(articleId: articleId) } catch { guard let error = error as? NetworkError else { return } handleError(error) @@ -106,7 +109,7 @@ extension ArticleDetailViewController { Task { do { let bookmarkRequest = BookmarkRequest(articleId: articleId, bookmarkRequestStatus: isSelected) - try await serviceProtocol.postBookmark(model: bookmarkRequest) + try await manager.postBookmark(model: bookmarkRequest) isBookMarked = isSelected } catch { @@ -123,7 +126,8 @@ extension ArticleDetailViewController: ViewControllerServiceable { switch error { case .unAuthorizedError: guard let window = self.view.window else { return } - ViewControllerUtil.setRootViewController(window: window, viewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))), withAnimation: false) + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + ViewControllerUtil.setRootViewController(window: window, viewController: splashViewController, withAnimation: false) case .clientError(_, let message): LHToast.show(message: "\(message)") default: diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByCategory/ViewControllers/ArticleListByCategoryViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByCategory/ViewControllers/ArticleListByCategoryViewController.swift index 17b87682..04a93f50 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByCategory/ViewControllers/ArticleListByCategoryViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByCategory/ViewControllers/ArticleListByCategoryViewController.swift @@ -9,9 +9,16 @@ import UIKit import SnapKit + +protocol ArticleListByCategoryManager { + func getArticleListByCategory(categoryString: String) async throws -> CurriculumWeekData + func postBookmark(model: BookmarkRequest) async throws +} + + final class ArticleListByCategoryViewController: UIViewController { - private let serviceProcotol: BookmarkOutProtocol + private let manager: ArticleListByCategoryManager var categoryString = String() var articleListData: [ArticleDataByWeek] = [] { @@ -36,9 +43,8 @@ final class ArticleListByCategoryViewController: UIViewController { return tableView }() - init(serviceProcotol: BookmarkOutProtocol) { - self.serviceProcotol = serviceProcotol - + init(manager: ArticleListByCategoryManager) { + self.manager = manager super.init(nibName: nil, bundle: nil) } @@ -53,7 +59,6 @@ final class ArticleListByCategoryViewController: UIViewController { setLayout() setDelegate() setTableView() - setNotificationCenter() } override func viewWillAppear(_ animated: Bool) { @@ -61,7 +66,7 @@ final class ArticleListByCategoryViewController: UIViewController { showLoading() Task { do { - self.articleListData = try await ArticleService.shared.getArticleListByCategory(categoryString: categoryString).articleData + self.articleListData = try await manager.getArticleListByCategory(categoryString: categoryString).articleData self.articleListTableView.reloadData() hideLoading() } catch { @@ -102,26 +107,6 @@ private extension ArticleListByCategoryViewController { func setTableView() { CurriculumArticleByWeekTableViewCell.register(to: articleListTableView) } - - func setNotificationCenter() { -// NotificationCenter.default.addObserver(self, selector: #selector(bookmarkButtonTapped), name: NSNotification.Name("isArticleBookmarked"), object: nil) - } - -// @objc func bookmarkButtonTapped(notification: NSNotification) { -// Task { -// do { -// guard let indexPath = notification.userInfo?["bookmarkCellIndexPath"] as? Int else { return } -// guard let buttonSelected = notification.userInfo?["bookmarkButtonSelected"] as? Bool else { return } -// -// try await BookmarkService.shared.postBookmark(BookmarkRequest(articleId: articleListData[indexPath+1].articleId, -// bookmarkStatus: buttonSelected)) -// buttonSelected ? LHToast.show(message: "북마크에 추가되었습니다", isTabBar: true) : LHToast.show(message: "북마크에 해제되었습니다", isTabBar: true) -// } catch { -// guard let error = error as? NetworkError else { return } -// handleError(error) -// } -// } -// } } extension ArticleListByCategoryViewController: ViewControllerServiceable { @@ -137,7 +122,8 @@ extension ArticleListByCategoryViewController: ViewControllerServiceable { LHToast.show(message: "Image Error") case .unAuthorizedError: guard let window = self.view.window else { return } - ViewControllerUtil.setRootViewController(window: window, viewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))), withAnimation: false) + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + ViewControllerUtil.setRootViewController(window: window, viewController: splashViewController, withAnimation: false) case .clientError(_, let message): LHToast.show(message: message) case .serverError: @@ -160,7 +146,7 @@ extension ArticleListByCategoryViewController: UITableViewDataSource { Task { do { - try await self.serviceProcotol.postBookmark(model: BookmarkRequest(articleId: self.articleListData[indexPath.row].articleId, + try await self.manager.postBookmark(model: BookmarkRequest(articleId: self.articleListData[indexPath.row].articleId, bookmarkRequestStatus: isSelected)) print(self.articleListData[indexPath.row].articleId) isSelected ? LHToast.show(message: "북마크에 추가되었습니다", isTabBar: true) : LHToast.show(message: "북마크에 해제되었습니다", isTabBar: true) diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByWeek/Cells/ArticleListByWeekTableViewCell.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByWeek/Cells/ArticleListByWeekTableViewCell.swift deleted file mode 100644 index b2d5a4f7..00000000 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByWeek/Cells/ArticleListByWeekTableViewCell.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// ArticleListByWeekTableViewCell.swift -// LionHeart-iOS -// -// Created by uiskim on 2023/07/09. -// Copyright (c) 2023 ArticleListByWeek. All rights reserved. -// - -import UIKit - -import SnapKit - -final class ArticleListByWeekTableViewCell: UITableViewCell, TableViewCellRegisterDequeueProtocol { - - var inputData: DummyModel? { - didSet { - /// action - } - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - // MARK: - 컴포넌트 설정 - setUI() - - // MARK: - addsubView - setHierarchy() - - // MARK: - autolayout설정 - setLayout() - - // MARK: - button의 addtarget설정 - setAddTarget() - - // MARK: - delegate설정 - setDelegate() - } - - @available(*, unavailable) - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} - -private extension ArticleListByWeekTableViewCell { - func setUI() { - - } - - func setHierarchy() { - - } - - func setLayout() { - - } - - func setAddTarget() { - - } - - func setDelegate() { - - } -} diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByWeek/ViewControllers/ArticleListByWeekViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByWeek/ViewControllers/ArticleListByWeekViewController.swift deleted file mode 100644 index 64723c9d..00000000 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByWeek/ViewControllers/ArticleListByWeekViewController.swift +++ /dev/null @@ -1,56 +0,0 @@ -// -// ArticleListByWeekViewController.swift -// LionHeart-iOS -// -// Created by uiskim on 2023/07/09. -// Copyright (c) 2023 ArticleListByWeek. All rights reserved. -// - -import UIKit - -import SnapKit - -final class ArticleListByWeekViewController: UIViewController { - - - public override func viewDidLoad() { - super.viewDidLoad() - // MARK: - 컴포넌트 설정 - setUI() - - // MARK: - addsubView - setHierarchy() - - // MARK: - autolayout설정 - setLayout() - - // MARK: - button의 addtarget설정 - setAddTarget() - - // MARK: - delegate설정 - setDelegate() - - } -} - -private extension ArticleListByWeekViewController { - func setUI() { - - } - - func setHierarchy() { - - } - - func setLayout() { - - } - - func setAddTarget() { - - } - - func setDelegate() { - - } -} diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByWeek/Views/ArticleListByWeekView.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByWeek/Views/ArticleListByWeekView.swift deleted file mode 100644 index 1c7c8fe5..00000000 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByWeek/Views/ArticleListByWeekView.swift +++ /dev/null @@ -1,60 +0,0 @@ -// -// ArticleListByWeekView.swift -// LionHeart-iOS -// -// Created by uiskim on 2023/07/09. -// Copyright (c) 2023 ArticleListByWeek. All rights reserved. -// - -import UIKit - -import SnapKit - -final class ArticleListByWeekView: UIView { - - override init(frame: CGRect) { - super.init(frame: frame) - // MARK: - 컴포넌트 설정 - setUI() - - // MARK: - addsubView - setHierarchy() - - // MARK: - autolayout설정 - setLayout() - - // MARK: - button의 addtarget설정 - setAddTarget() - - // MARK: - delegate설정 - setDelegate() - } - - @available(*, unavailable) - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - -} - -private extension ArticleListByWeekView { - func setUI() { - - } - - func setHierarchy() { - - } - - func setLayout() { - - } - - func setAddTarget() { - - } - - func setDelegate() { - - } -} diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/Model/BookmarkModel.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/Model/BookmarkModel.swift index 21691e6b..1e4ec572 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/Model/BookmarkModel.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/Model/BookmarkModel.swift @@ -12,6 +12,12 @@ struct BookmarkAppData: AppData { let articleSummaries: [ArticleSummaries] } +extension BookmarkAppData { + static var empty: Self { + return .init(nickName: "", articleSummaries: []) + } +} + struct ArticleSummaries: AppData { let title: String let articleID: Int diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/ViewControllers/BookmarkViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/ViewControllers/BookmarkViewController.swift index a23a25b3..080bdbc3 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/ViewControllers/BookmarkViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/ViewControllers/BookmarkViewController.swift @@ -10,9 +10,14 @@ import UIKit import SnapKit +protocol BookmarkManger { + func getBookmark() async throws -> BookmarkAppData + func postBookmark(model: BookmarkRequest) async throws +} + final class BookmarkViewController: UIViewController { - private let serviceProtocol: BookmarkInOutServiceProtocol + private let manager: BookmarkManger private var bookmarkAppData = BookmarkAppData(nickName: "", articleSummaries: [ArticleSummaries]()) private var bookmarkList = [ArticleSummaries]() @@ -26,12 +31,11 @@ final class BookmarkViewController: UIViewController { return collectionView }() - init(serviceProtocol: BookmarkInOutServiceProtocol) { - self.serviceProtocol = serviceProtocol - + init(manager: BookmarkManger) { + self.manager = manager super.init(nibName: nil, bundle: nil) } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -51,7 +55,7 @@ final class BookmarkViewController: UIViewController { showLoading() Task { do { - self.bookmarkAppData = try await serviceProtocol.getBookmark() + self.bookmarkAppData = try await manager.getBookmark() self.bookmarkList = bookmarkAppData.articleSummaries hideLoading() bookmarkCollectionView.reloadData() @@ -118,7 +122,8 @@ extension BookmarkViewController: ViewControllerServiceable { LHToast.show(message: "Image Error") case .unAuthorizedError: guard let window = self.view.window else { return } - ViewControllerUtil.setRootViewController(window: window, viewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))), withAnimation: false) + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + ViewControllerUtil.setRootViewController(window: window, viewController: splashViewController, withAnimation: false) case .clientError(_, let message): LHToast.show(message: message) case .serverError: @@ -158,7 +163,7 @@ extension BookmarkViewController: UICollectionViewDataSource { cell.bookmarkButtonClosure = { indexPath in Task { do { - try await self.serviceProtocol.postBookmark(model: BookmarkRequest(articleId: self.bookmarkList[indexPath.item].articleID, + try await self.manager.postBookmark(model: BookmarkRequest(articleId: self.bookmarkList[indexPath.item].articleID, bookmarkRequestStatus: !self.bookmarkList[indexPath.item].bookmarked)) self.bookmarkList.remove(at: indexPath.item) collectionView.deleteItems(at: [indexPath]) diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/Model/ChallengeData.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/Model/ChallengeData.swift index 7c3a99f8..c3ba77c7 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/Model/ChallengeData.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/Model/ChallengeData.swift @@ -13,3 +13,9 @@ struct ChallengeData: AppData { let daddyLevel: String let daddyAttendances: [String] } + +extension ChallengeData { + static var empty: Self { + return .init(babyDaddyName: "", howLongDay: 0, daddyLevel: "", daddyAttendances: []) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/ViewController/ChallengeViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/ViewController/ChallengeViewController.swift index d5516f30..f98acba4 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/ViewController/ChallengeViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/ViewController/ChallengeViewController.swift @@ -11,74 +11,36 @@ import UIKit import SnapKit import Lottie -enum BadgeLevel: String { - case level01 = "LEVEL_ONE" - case level02 = "LEVEL_TWO" - case level03 = "LEVEL_THREE" - case level04 = "LEVEL_FOUR" - case level05 = "LEVEL_FIVE" - - var badgeLevel: Int { - switch self { - case .level01: return 1 - case .level02: return 2 - case .level03: return 3 - case .level04: return 4 - case .level05: return 5 - } - } - - var badgeImage: UIImage { - switch self { - case .level01: return ImageLiterals.ChallengeBadge.level01 - case .level02: return ImageLiterals.ChallengeBadge.level02 - case .level03: return ImageLiterals.ChallengeBadge.level03 - case .level04: return ImageLiterals.ChallengeBadge.level04 - case .level05: return ImageLiterals.ChallengeBadge.level05 - } - } - - var progreddbarLottie: String { - switch self { - case .level01: return "Level1" - case .level02: return "Level2" - case .level03: return "Level3" - case .level04: return "Level4" - case .level05: return "Level5" - } - } +protocol ChallengeManager { + func inquireChallengeInfo() async throws -> ChallengeData } final class ChallengeViewController: UIViewController { + private enum Size { + static let cellOffset: CGFloat = 40 + static let numberOfCellsinRow: CGFloat = 0 + } + + private var manager: ChallengeManager + var inputData: ChallengeData? { didSet { guard let babyNickname = inputData?.babyDaddyName else { return } - self.nicknameLabel.text = "\(babyNickname)아빠 님," - - if let howLongDay = inputData?.howLongDay { - self.challengeDayLabel.text = "\(howLongDay)일째 도전 중" - } - - self.levelBadge.image = BadgeLevel(rawValue: inputData?.daddyLevel ?? "")?.badgeImage - - self.lottieImageView.animation = .named(BadgeLevel(rawValue: inputData?.daddyLevel ?? "")?.progreddbarLottie ?? "") - self.lottieImageView.play() - - let fullText = "사자력 Lv." + String(BadgeLevel(rawValue: inputData?.daddyLevel ?? "")?.badgeLevel ?? 1) - - let attributtedString = NSMutableAttributedString(string: fullText) - attributtedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.designSystem(.white) ?? .white, range: (fullText as NSString).range(of: "Lv." + String(BadgeLevel(rawValue: inputData?.daddyLevel ?? "")?.badgeLevel ?? 1))) - - self.challengelevelLabel.attributedText = attributtedString + configureData(babyNickname) + } } - private enum Size { - static let cellOffset: CGFloat = 40 - static let numberOfCellsinRow: CGFloat = 0 + init(manager: ChallengeManager) { + self.manager = manager + super.init(nibName: nil, bundle: nil) } + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + private let leftSeperateLine: UIView = { let view = UIView() view.backgroundColor = .designSystem(.background) @@ -144,7 +106,7 @@ final class ChallengeViewController: UIViewController { Task { do { self.showLoading() - let model = try await ChallengeService.shared.inquireChallengeInfo() + let model = try await manager.inquireChallengeInfo() self.inputData = model self.tags = model.daddyAttendances self.challengeDayCheckCollectionView.reloadData() @@ -249,16 +211,35 @@ private extension ChallengeViewController { func setAddTarget() { navigationBar.rightFirstBarItemAction { - let bookmarkViewController = BookmarkViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) + let bookmarkViewController = BookmarkViewController(manager: BookmarkMangerImpl(bookmarkService: BookmarkServiceImpl(apiService: APIService()))) self.navigationController?.pushViewController(bookmarkViewController, animated: true) } navigationBar.rightSecondBarItemAction { - let wrapper = AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService())) - let myPageViewController = MyPageViewController(service: wrapper) + let myPageViewController = MyPageViewController(manager: MyPageManagerImpl(mypageService: MyPageServiceImpl(apiService: APIService()), authService: AuthServiceImpl(apiService: APIService()))) self.navigationController?.pushViewController(myPageViewController, animated: true) } } + + func configureData(_ babyNickname: String) { + self.nicknameLabel.text = "\(babyNickname)아빠 님," + + if let howLongDay = inputData?.howLongDay { + self.challengeDayLabel.text = "\(howLongDay)일째 도전 중" + } + + self.levelBadge.image = BadgeLevel(rawValue: inputData?.daddyLevel ?? "")?.badgeImage + + self.lottieImageView.animation = .named(BadgeLevel(rawValue: inputData?.daddyLevel ?? "")?.progreddbarLottie ?? "") + self.lottieImageView.play() + + let fullText = "사자력 Lv." + String(BadgeLevel(rawValue: inputData?.daddyLevel ?? "")?.badgeLevel ?? 1) + + let attributtedString = NSMutableAttributedString(string: fullText) + attributtedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.designSystem(.white) ?? .white, range: (fullText as NSString).range(of: "Lv." + String(BadgeLevel(rawValue: inputData?.daddyLevel ?? "")?.badgeLevel ?? 1))) + + self.challengelevelLabel.attributedText = attributtedString + } } extension ChallengeViewController: diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumListByWeekViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumListByWeekViewController.swift index 14ecdb85..af3d9e7b 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumListByWeekViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumListByWeekViewController.swift @@ -10,13 +10,17 @@ import UIKit import SnapKit +protocol CurriculumListManager { + func postBookmark(model: BookmarkRequest) async throws + func getArticleListByWeekInfo(week: Int) async throws -> CurriculumWeekData +} + final class CurriculumListByWeekViewController: UIViewController { - private let serviceProtocol: BookmarkOutProtocol + private let manager: CurriculumListManager - init(serviceProtocol: BookmarkOutProtocol) { - self.serviceProtocol = serviceProtocol - /// 이 코드는 왜 있어야 하지? + init(manager: CurriculumListManager) { + self.manager = manager super.init(nibName: nil, bundle: nil) } @@ -52,7 +56,7 @@ final class CurriculumListByWeekViewController: UIViewController { if oldValue == currentPage { return } Task { showLoading() - let articlesByWeek = try await CurriculumService.shared.getArticleListByWeekInfo(week: week) + let articlesByWeek = try await manager.getArticleListByWeekInfo(week: week) print("✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨") print(currentPage + 4) self.listByWeekDatas = articlesByWeek @@ -180,7 +184,7 @@ private extension CurriculumListByWeekViewController { print(buttonSelected) try await - serviceProtocol.postBookmark(model: BookmarkRequest(articleId: listByWeekDatas.articleData[indexPath].articleId, + manager.postBookmark(model: BookmarkRequest(articleId: listByWeekDatas.articleData[indexPath].articleId, bookmarkRequestStatus: buttonSelected)) hideLoading() buttonSelected ? LHToast.show(message: "북마크가 추가되었습니다", isTabBar: true) : LHToast.show(message: "북마크가 해제되었습니다", isTabBar: true) @@ -261,7 +265,8 @@ extension CurriculumListByWeekViewController: ViewControllerServiceable { switch error { case .unAuthorizedError: guard let window = self.view.window else { return } - ViewControllerUtil.setRootViewController(window: window, viewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))), withAnimation: false) + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + ViewControllerUtil.setRootViewController(window: window, viewController: splashViewController, withAnimation: false) case .clientError(code: _, message: let message): LHToast.show(message: "\(message)") default: @@ -274,8 +279,7 @@ extension CurriculumListByWeekViewController { func getListByWeekData() { Task { do { - let responseListByWeek = try await CurriculumService.shared.getArticleListByWeekInfo(week: weekToIndexPathItem + 4) - + let responseListByWeek = try await manager.getArticleListByWeekInfo(week: weekToIndexPathItem + 4) listByWeekDatas = responseListByWeek hideLoading() } catch { diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift index 8b1a1627..d36be9f9 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift @@ -11,6 +11,10 @@ import UIKit import SnapKit import Lottie +protocol CurriculumManager { + func getCurriculumServiceInfo() async throws -> UserInfoData +} + final class CurriculumViewController: UIViewController, CurriculumTableViewToggleButtonTappedProtocol{ private lazy var navigationBar = LHNavigationBarView(type: .curriculumMain, viewController: self) @@ -21,6 +25,17 @@ final class CurriculumViewController: UIViewController, CurriculumTableViewToggl } } + private let manager: CurriculumManager + + init(manager: CurriculumManager) { + self.manager = manager + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + private let progressBar = LottieAnimationView() private let dDayLabel: UILabel = { @@ -166,13 +181,12 @@ private extension CurriculumViewController { func setAddTarget() { navigationBar.rightFirstBarItemAction { - let bookmarkViewController = BookmarkViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) + let bookmarkViewController = BookmarkViewController(manager: BookmarkMangerImpl(bookmarkService: BookmarkServiceImpl(apiService: APIService()))) self.navigationController?.pushViewController(bookmarkViewController, animated: true) } navigationBar.rightSecondBarItemAction { - let wrapper = AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService())) - let myPageViewController = MyPageViewController(service: wrapper) + let myPageViewController = MyPageViewController(manager: MyPageManagerImpl(mypageService: MyPageServiceImpl(apiService: APIService()), authService: AuthServiceImpl(apiService: APIService()))) self.navigationController?.pushViewController(myPageViewController, animated: true) } } @@ -268,7 +282,7 @@ extension CurriculumViewController: UITableViewDataSource { } - let listByWeekVC = CurriculumListByWeekViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) + let listByWeekVC = CurriculumListByWeekViewController(manager: CurriculumListManagerImpl(bookmarkService: BookmarkServiceImpl(apiService: APIService()), curriculumService: CurriculumServiceImpl(apiService: APIService()))) listByWeekVC.weekToIndexPathItem = (indexPath.section * 4) + indexPath.row self.navigationController?.pushViewController(listByWeekVC, animated: true) @@ -277,12 +291,7 @@ extension CurriculumViewController: UITableViewDataSource { } -extension CurriculumViewController: UITableViewDelegate{ -// func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { -// let curriculumListByWeekViewController = CurriculumListByWeekViewController() -// self.navigationController?.pushViewController(curriculumListByWeekViewController, animated: true) -// } -} +extension CurriculumViewController: UITableViewDelegate{} extension CurriculumViewController: ViewControllerServiceable { @@ -290,7 +299,8 @@ extension CurriculumViewController: ViewControllerServiceable { switch error { case .unAuthorizedError: guard let window = self.view.window else { return } - ViewControllerUtil.setRootViewController(window: window, viewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))), withAnimation: false) + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + ViewControllerUtil.setRootViewController(window: window, viewController: splashViewController, withAnimation: false) case .clientError(_, let message): LHToast.show(message: "\(message)") default: @@ -305,7 +315,7 @@ extension CurriculumViewController { func getCurriculumData() { Task { do { - let responseCurriculum = try await CurriculumService.shared.getCurriculumServiceInfo() + let responseCurriculum = try await manager.getCurriculumServiceInfo() userInfoData = responseCurriculum hideLoading() diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Login/LoginViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Login/LoginViewController.swift index d51e93ae..eef5fad4 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Login/LoginViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Login/LoginViewController.swift @@ -13,6 +13,10 @@ import SnapKit import KakaoSDKAuth import KakaoSDKUser +protocol LoginManager { + func login(type: LoginType, kakaoToken: String) async throws +} + final class LoginViewController: UIViewController { private var kakaoAccessToken: String? { @@ -25,7 +29,7 @@ final class LoginViewController: UIViewController { } } - private let authService: AuthServiceProtocol + private let manager: LoginManager private let loginMainImageView: UIImageView = { let imageView = UIImageView(image: ImageLiterals.Login.loginBackgroundImage) @@ -60,8 +64,8 @@ final class LoginViewController: UIViewController { return button }() - init(authService: AuthServiceProtocol) { - self.authService = authService + init(manager: LoginManager) { + self.manager = manager super.init(nibName: nil, bundle: nil) } @@ -99,7 +103,7 @@ extension LoginViewController { private func loginAPI(kakaoToken: String) { Task { do { - try await authService.login(type: .kakao, kakaoToken: kakaoToken) + try await manager.login(type: .kakao, kakaoToken: kakaoToken) guard let window = self.view.window else { LHToast.show(message: "로그인api에서 window guard let 88") return @@ -117,7 +121,7 @@ extension LoginViewController { } func moveUserToOnboardingViewController() { - let onboardingViewController = OnboardingViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))) + let onboardingViewController = OnboardingViewController(manager: OnboardingManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) onboardingViewController.setKakaoAccessToken(kakaoAccessToken) self.navigationController?.pushViewController(onboardingViewController, animated: true) } diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/MyPage/ViewControllers/MyPageViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/MyPage/ViewControllers/MyPageViewController.swift index c1d619bb..bac9f595 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/MyPage/ViewControllers/MyPageViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/MyPage/ViewControllers/MyPageViewController.swift @@ -10,7 +10,7 @@ import UIKit import SnapKit -protocol MyPageServiceProtocol: AnyObject { +protocol MyPageManager { func getMyPage() async throws -> MyPageAppData func resignUser() async throws func logout(token: UserDefaultToken) async throws @@ -30,7 +30,7 @@ final class MyPageViewController: UIViewController { } } - private let service: MyPageServiceProtocol + private let manager: MyPageManager // MARK: - UI Components @@ -49,11 +49,11 @@ final class MyPageViewController: UIViewController { return button }() - init(service: MyPageServiceProtocol) { - self.service = service + init(manager: MyPageManager) { + self.manager = manager super.init(nibName: nil, bundle: nil) } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -76,7 +76,7 @@ final class MyPageViewController: UIViewController { Task { do { - let data = try await service.getMyPage() + let data = try await manager.getMyPage() myPageAppData = data } catch { guard let error = error as? NetworkError else { return } @@ -125,8 +125,9 @@ private extension MyPageViewController { do { guard let window = self.view.window else { return } self.resignButton.isUserInteractionEnabled = false - try await self.service.resignUser() - ViewControllerUtil.setRootViewController(window: window, viewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))), withAnimation: false) + try await self.manager.resignUser() + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + ViewControllerUtil.setRootViewController(window: window, viewController: splashViewController, withAnimation: false) } catch { print(error) } @@ -168,7 +169,8 @@ extension MyPageViewController: ViewControllerServiceable { LHToast.show(message: "Image Error") case .unAuthorizedError: guard let window = self.view.window else { return } - ViewControllerUtil.setRootViewController(window: window, viewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))), withAnimation: false) + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + ViewControllerUtil.setRootViewController(window: window, viewController: splashViewController, withAnimation: false) case .clientError(_, let message): LHToast.show(message: message) case .serverError: diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Onboarding/ViewControllers/OnboardingViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Onboarding/ViewControllers/OnboardingViewController.swift index 0dcb76ac..bfb772b5 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Onboarding/ViewControllers/OnboardingViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Onboarding/ViewControllers/OnboardingViewController.swift @@ -10,11 +10,15 @@ import UIKit import SnapKit +protocol OnboardingManager { + func signUp(type: LoginType, onboardingModel: UserOnboardingModel) async throws +} + final class OnboardingViewController: UIViewController { typealias OnboardingViews = [UIViewController] - private let authService: AuthServiceProtocol + private let manager: OnboardingManager /// passing data property private var fetalNickName: String? @@ -50,8 +54,8 @@ final class OnboardingViewController: UIViewController { } } - init(authService: AuthServiceProtocol) { - self.authService = authService + init(manager: OnboardingManager) { + self.manager = manager super.init(nibName: nil, bundle: nil) } @@ -181,7 +185,7 @@ private extension OnboardingViewController { Task { showLoading() do { - try await authService.signUp(type: .kakao, onboardingModel: passingData) + try await manager.signUp(type: .kakao, onboardingModel: passingData) hideLoading() self.navigationController?.pushViewController(completeViewController, animated: true) @@ -248,7 +252,8 @@ extension OnboardingViewController: ViewControllerServiceable { LHToast.show(message: "이미지패치에러") case .unAuthorizedError: guard let window = self.view.window else { return } - ViewControllerUtil.setRootViewController(window: window, viewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))), withAnimation: false) + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + ViewControllerUtil.setRootViewController(window: window, viewController: splashViewController, withAnimation: false) case .clientError(_, let message): LHToast.show(message: message) case .serverError: diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Splash/SplashViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Splash/SplashViewController.swift index bc5c82e4..60285493 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Splash/SplashViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Splash/SplashViewController.swift @@ -11,19 +11,11 @@ import UIKit import SnapKit import Lottie -protocol UserInProtocol { +protocol SplashManager { func reissueToken(token: Token) async throws -> Token? - func login(type: LoginType, kakaoToken: String) async throws - func signUp(type: LoginType, onboardingModel: UserOnboardingModel) async throws -} - -protocol UserOutProtocol { - func resignUser() async throws func logout(token: UserDefaultToken) async throws } -protocol AuthServiceProtocol: UserInProtocol, UserOutProtocol {} - final class SplashViewController: UIViewController { // MARK: - UI Components @@ -36,12 +28,12 @@ final class SplashViewController: UIViewController { // MARK: - Properties - private let authService: AuthServiceProtocol + private let manager: SplashManager // MARK: - Life Cycle - init(authService: AuthServiceProtocol) { - self.authService = authService + init(manager: SplashManager) { + self.manager = manager super.init(nibName: nil, bundle: nil) } @@ -59,7 +51,7 @@ final class SplashViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { lottieImageView.play { _ in guard let accessToken = UserDefaultsManager.tokenKey?.accessToken, let refreshToken = UserDefaultsManager.tokenKey?.refreshToken else { - let loginViewController = UINavigationController(rootViewController: LoginViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService())))) + let loginViewController = UINavigationController(rootViewController: LoginViewController(manager: LoginMangerImpl(authService: AuthServiceImpl(apiService: APIService())))) guard let window = self.view.window else { return } ViewControllerUtil.setRootViewController(window: window, viewController: loginViewController, withAnimation: true) return @@ -111,7 +103,7 @@ private extension SplashViewController { func reissueToken(refreshToken: String, accessToken: String) async throws { do { - let dtoToken = try await authService.reissueToken(token: Token(accessToken: accessToken, refreshToken: refreshToken)) + let dtoToken = try await manager.reissueToken(token: Token(accessToken: accessToken, refreshToken: refreshToken)) UserDefaultsManager.tokenKey?.accessToken = dtoToken?.accessToken UserDefaultsManager.tokenKey?.refreshToken = dtoToken?.refreshToken @@ -125,7 +117,7 @@ private extension SplashViewController { func logout(token: UserDefaultToken) async { do { - try await authService.logout(token: token) + try await manager.logout(token: token) } catch { print(error) } @@ -138,10 +130,10 @@ private extension SplashViewController { guard let token = UserDefaultsManager.tokenKey else { return } await logout(token: token) // LoginVC로 이동하기 - let loginVC = UINavigationController(rootViewController: LoginViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService())))) + let loginVC = UINavigationController(rootViewController: LoginViewController(manager: LoginMangerImpl(authService: AuthServiceImpl(apiService: APIService())))) setRootViewController(to: loginVC, animation: true) } else if code == NetworkErrorCode.unfoundUserErrorCode { - let loginVC = UINavigationController(rootViewController: LoginViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService())))) + let loginVC = UINavigationController(rootViewController: LoginViewController(manager: LoginMangerImpl(authService: AuthServiceImpl(apiService: APIService())))) setRootViewController(to: loginVC, animation: true) } default: diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/TabBar/TabBarViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/TabBar/TabBarViewController.swift index 675ffba4..176d7fb1 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/TabBar/TabBarViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/TabBar/TabBarViewController.swift @@ -14,16 +14,16 @@ final class TabBarViewController: UITabBarController { public override func viewDidLoad() { super.viewDidLoad() - let todayViewController = UINavigationController(rootViewController: TodayViewController()) + let todayViewController = UINavigationController(rootViewController: TodayViewController(manager: TodayManagerImpl(articleService: ArticleServiceImpl(apiService: APIService())))) todayViewController.tabBarItem = UITabBarItem(title: "투데이", image: .assetImage(.home), tag: 0) let articleCategoryViewController = UINavigationController(rootViewController: ArticleCategoryViewController()) articleCategoryViewController.tabBarItem = UITabBarItem(title: "탐색", image: .assetImage(.search), tag: 1) - let curriculumViewController = UINavigationController(rootViewController: CurriculumViewController()) + let curriculumViewController = UINavigationController(rootViewController: CurriculumViewController(manager: CurriculumManagerImpl(curriculumService: CurriculumServiceImpl(apiService: APIService())))) curriculumViewController.tabBarItem = UITabBarItem(title: "커리큘럼", image: .assetImage(.curriculum), tag: 2) - let challengeViewController = UINavigationController(rootViewController: ChallengeViewController()) + let challengeViewController = UINavigationController(rootViewController: ChallengeViewController(manager: ChallengeManagerImpl(challengeService: ChallengeServiceImpl(apiService: APIService())))) challengeViewController.tabBarItem = UITabBarItem(title: "챌린지", image: .assetImage(.challenge), tag: 3) self.viewControllers = [todayViewController, articleCategoryViewController, curriculumViewController, challengeViewController] diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Today/ViewControllers/TodayViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Today/ViewControllers/TodayViewController.swift index 97ba1eac..05c925e9 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Today/ViewControllers/TodayViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Today/ViewControllers/TodayViewController.swift @@ -10,8 +10,23 @@ import UIKit import SnapKit +protocol TodayManager { + func inquiryTodayArticle() async throws -> TodayArticle +} + final class TodayViewController: UIViewController { + private let manager: TodayManager + + init(manager: TodayManager) { + self.manager = manager + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + enum TodayArticleImage { static let ratio: CGFloat = 400/335 } @@ -54,7 +69,7 @@ extension TodayViewController { func getInquireTodayArticle() { Task { do { - let responseArticle = try await ArticleService.shared.inquiryTodayArticle() + let responseArticle = try await manager.inquiryTodayArticle() let image = try await LHKingFisherService.fetchImage(with: responseArticle.mainImageURL) mainArticleView.mainArticlImageView.image = image titleLabel.userNickName = responseArticle.fetalNickname @@ -125,13 +140,12 @@ private extension TodayViewController { func setButtonAction() { todayNavigationBar.rightFirstBarItemAction { - let bookmarkViewController = BookmarkViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) + let bookmarkViewController = BookmarkViewController(manager: BookmarkMangerImpl(bookmarkService: BookmarkServiceImpl(apiService: APIService()))) self.navigationController?.pushViewController(bookmarkViewController, animated: true) } todayNavigationBar.rightSecondBarItemAction { - let wrapperClass = AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService())) - let myPageViewController = MyPageViewController(service: wrapperClass) + let myPageViewController = MyPageViewController(manager: MyPageManagerImpl(mypageService: MyPageServiceImpl(apiService: APIService()), authService: AuthServiceImpl(apiService: APIService()))) self.navigationController?.pushViewController(myPageViewController, animated: true) } } @@ -156,7 +170,8 @@ extension TodayViewController: ViewControllerServiceable { LHToast.show(message: "이미지패치실패", isTabBar: true) case .unAuthorizedError: guard let window = self.view.window else { return } - ViewControllerUtil.setRootViewController(window: window, viewController: SplashViewController(authService: AuthMyPageServiceWrapper(authAPIService: AuthAPI(apiService: APIService()), mypageAPIService: MyPageAPI(apiService: APIService()))), withAnimation: false) + let splashViewController = SplashViewController(manager: SplashManagerImpl(authService: AuthServiceImpl(apiService: APIService()))) + ViewControllerUtil.setRootViewController(window: window, viewController: splashViewController, withAnimation: false) case .clientError(_, let message): LHToast.show(message: message, isTabBar: true) case .serverError: