From e7c0197b987e6300a78f78d6d9d48b4896b73b8a Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Wed, 13 Mar 2024 17:12:08 +0900 Subject: [PATCH 01/16] =?UTF-8?q?[Add]=20#243=20-=20=EC=98=A8=EB=B3=B4?= =?UTF-8?q?=EB=94=A9=20ViewModel=20=ED=94=84=EB=A1=9C=ED=86=A0=EC=BD=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iOS-NOTTODO.xcodeproj/project.pbxproj | 18 ++++++++++-- .../Coordinator/Protocol/ViewModel.swift | 15 ++++++++++ .../Onboarding/Model/OnboardingModel.swift | 29 ++++++++++--------- .../ViewModel/OnboardingViewModel.swift | 19 ++++++++++++ 4 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Coordinator/Protocol/ViewModel.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/OnboardingViewModel.swift diff --git a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj index 97e0f111..4a4affef 100644 --- a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj +++ b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj @@ -62,7 +62,6 @@ 099FC98929B3233D005B37E6 /* CalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099FC98829B3233D005B37E6 /* CalendarView.swift */; }; 09A1465F2A192C4900DDC308 /* WeekMissionResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09A1465E2A192C4900DDC308 /* WeekMissionResponseDTO.swift */; }; 09A146652A1964B500DDC308 /* AddAnotherDayResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09A146642A19649A00DDC308 /* AddAnotherDayResponseDTO.swift */; }; - 09A8E48C2B9DBE5C00C0F48F /* API_KEY.plist in Resources */ = {isa = PBXBuildFile; fileRef = 09A8E48B2B9DBE5C00C0F48F /* API_KEY.plist */; }; 09A8E48E2B9DBEC700C0F48F /* BaseAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09A8E48D2B9DBEC700C0F48F /* BaseAPI.swift */; }; 09C8602D2AB14B4800C4F4B1 /* FSCalendar in Frameworks */ = {isa = PBXBuildFile; productRef = 09C8602C2AB14B4800C4F4B1 /* FSCalendar */; }; 09CF56022B09E98A00526C8C /* DetailAchieveHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09CF56012B09E98A00526C8C /* DetailAchieveHeaderView.swift */; }; @@ -136,6 +135,8 @@ 3B710A5C2A62D4AB00E95620 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 3B710A5B2A62D4AB00E95620 /* Settings.bundle */; }; 3B80B5D52B7F304D00697250 /* adjust+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80B5D42B7F304D00697250 /* adjust+.swift */; }; 3B80B5D72B7F30E200697250 /* Numbers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80B5D62B7F30E200697250 /* Numbers.swift */; }; + 3B877D622BA195C40002DFCB /* OnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B877D612BA195C40002DFCB /* OnboardingViewModel.swift */; }; + 3B877D642BA1965F0002DFCB /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B877D632BA1965F0002DFCB /* ViewModel.swift */; }; 3B892ABB2A2FBD4C00A316BC /* RecommendSituationResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B892ABA2A2FBD4C00A316BC /* RecommendSituationResponseDTO.swift */; }; 3B9532F42A284CC1006510F8 /* ModalProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B9532F32A284CC1006510F8 /* ModalProtocol.swift */; }; 3BBB6C8F2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BBB6C8E2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift */; }; @@ -244,7 +245,6 @@ 099FC98829B3233D005B37E6 /* CalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarView.swift; sourceTree = ""; }; 09A1465E2A192C4900DDC308 /* WeekMissionResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeekMissionResponseDTO.swift; sourceTree = ""; }; 09A146642A19649A00DDC308 /* AddAnotherDayResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAnotherDayResponseDTO.swift; sourceTree = ""; }; - 09A8E48B2B9DBE5C00C0F48F /* API_KEY.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = API_KEY.plist; path = ../../../../Desktop/API_KEY.plist; sourceTree = ""; }; 09A8E48D2B9DBEC700C0F48F /* BaseAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseAPI.swift; sourceTree = ""; }; 09CF56012B09E98A00526C8C /* DetailAchieveHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailAchieveHeaderView.swift; sourceTree = ""; }; 09CF56032B09F23800526C8C /* HomeDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeDataSource.swift; sourceTree = ""; }; @@ -314,6 +314,8 @@ 3B710A5B2A62D4AB00E95620 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 3B80B5D42B7F304D00697250 /* adjust+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "adjust+.swift"; sourceTree = ""; }; 3B80B5D62B7F30E200697250 /* Numbers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Numbers.swift; sourceTree = ""; }; + 3B877D612BA195C40002DFCB /* OnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewModel.swift; sourceTree = ""; }; + 3B877D632BA1965F0002DFCB /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = ""; }; 3B892ABA2A2FBD4C00A316BC /* RecommendSituationResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendSituationResponseDTO.swift; sourceTree = ""; }; 3B9532F32A284CC1006510F8 /* ModalProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalProtocol.swift; sourceTree = ""; }; 3BBB6C8E2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewLeftAlignLayout.swift; sourceTree = ""; }; @@ -512,6 +514,7 @@ 098904432B81C18A004AAD3C /* HomeCoordinator.swift */, 098904452B81C191004AAD3C /* MypageCoordinator.swift */, 098904472B81C197004AAD3C /* AchieveCoordinator.swift */, + 3B877D632BA1965F0002DFCB /* ViewModel.swift */, ); path = Protocol; sourceTree = ""; @@ -618,6 +621,7 @@ 09F6717E29CAD68100708725 /* Onboarding */ = { isa = PBXGroup; children = ( + 3B877D602BA195A80002DFCB /* ViewModel */, 6C9628AA2A2220E2003ADE25 /* Lottie */, 09F6719229CB6E6200708725 /* ViewControllers */, 09F6719129CB6E4D00708725 /* Model */, @@ -1021,6 +1025,14 @@ path = AddMissionLabel; sourceTree = ""; }; + 3B877D602BA195A80002DFCB /* ViewModel */ = { + isa = PBXGroup; + children = ( + 3B877D612BA195C40002DFCB /* OnboardingViewModel.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; 3B892AB02A2FB63E00A316BC /* Recommend */ = { isa = PBXGroup; children = ( @@ -1382,6 +1394,7 @@ 098904382B81BC16004AAD3C /* AppCoordinator.swift in Sources */, 6C16016229C59EFD005AE3F5 /* MyInfoAccountModel.swift in Sources */, 3B027A92299C33FE00BEB65C /* UIColor+.swift in Sources */, + 3B877D622BA195C40002DFCB /* OnboardingViewModel.swift in Sources */, 092C09B52A484DD900E9B06B /* HomeDeleteViewController.swift in Sources */, 3B027AA4299C357000BEB65C /* MyInfoViewController.swift in Sources */, 0989043B2B81BCFA004AAD3C /* AppCoordinatorImpl.swift in Sources */, @@ -1502,6 +1515,7 @@ 09582B4F29BEBAFA00EF3207 /* DetailCalendarViewController.swift in Sources */, 09F6718829CB383800708725 /* ThirdOnboardingViewController.swift in Sources */, 3B37AE2B29C8904800AB7587 /* RecommendKeywordCollectionViewCell.swift in Sources */, + 3B877D642BA1965F0002DFCB /* ViewModel.swift in Sources */, 099FC98929B3233D005B37E6 /* CalendarView.swift in Sources */, 09ED941B2B2ABAB7001864EF /* CommonNotificationViewController.swift in Sources */, 6C9628A92A22209E003ADE25 /* LogoOnboardingViewController.swift in Sources */, diff --git a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Protocol/ViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Protocol/ViewModel.swift new file mode 100644 index 00000000..66a86741 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Protocol/ViewModel.swift @@ -0,0 +1,15 @@ +// +// ViewModel.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/13/24. +// + +import Foundation + +protocol ViewModel where Self: AnyObject { + associatedtype Input + associatedtype Output + + func transform(input: Input) -> Output +} diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Model/OnboardingModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Model/OnboardingModel.swift index 7a368fa9..31062e29 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Model/OnboardingModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Model/OnboardingModel.swift @@ -11,11 +11,12 @@ struct SecondOnboardingModel: Hashable { var title: String } extension SecondOnboardingModel { - static let titles: [SecondOnboardingModel] = [SecondOnboardingModel(title: "고치고 싶은 나쁜 습관이 있어요"), - SecondOnboardingModel(title: "루틴대로 하루를 보내지 못해요"), - SecondOnboardingModel(title: "계획만 세우고 목표를 달성하지 못해요"), - SecondOnboardingModel(title: "불필요한 행위로 시간을 뺏겨요"), - SecondOnboardingModel(title: "불편함은 없지만 낫투두를 시도하고 싶어요") + static let titles: [SecondOnboardingModel] = [ + SecondOnboardingModel(title: "고치고 싶은 나쁜 습관이 있어요"), + SecondOnboardingModel(title: "루틴대로 하루를 보내지 못해요"), + SecondOnboardingModel(title: "계획만 세우고 목표를 달성하지 못해요"), + SecondOnboardingModel(title: "불필요한 행위로 시간을 뺏겨요"), + SecondOnboardingModel(title: "불편함은 없지만 낫투두를 시도하고 싶어요") ] } @@ -40,19 +41,21 @@ struct FourthOnboardingModel: Hashable { var title: String } extension FourthOnboardingModel { - static let items: [FourthOnboardingModel] = [FourthOnboardingModel(icon: .youtube, tag: "취침 전", title: "유튜브 추천 영상 생각없이 보지 않기"), - FourthOnboardingModel(icon: .delivery, tag: "항상", title: "배민 VIP 탈출하기"), - FourthOnboardingModel(icon: .coffee, tag: "기상 직후", title: "공복에 커피 마시지 않기"), - FourthOnboardingModel(icon: .kakao, tag: "업무 중", title: "불필요한 PC 카톡 하지 않기"), - FourthOnboardingModel(icon: .nightmeal, tag: "취침 전", title: "자기 2시간 전 야식 먹지 않기") + static let items: [FourthOnboardingModel] = [ + FourthOnboardingModel(icon: .youtube, tag: "취침 전", title: "유튜브 추천 영상 생각없이 보지 않기"), + FourthOnboardingModel(icon: .delivery, tag: "항상", title: "배민 VIP 탈출하기"), + FourthOnboardingModel(icon: .coffee, tag: "기상 직후", title: "공복에 커피 마시지 않기"), + FourthOnboardingModel(icon: .kakao, tag: "업무 중", title: "불필요한 PC 카톡 하지 않기"), + FourthOnboardingModel(icon: .nightmeal, tag: "취침 전", title: "자기 2시간 전 야식 먹지 않기") ] } struct FifthOnboardingModel: Hashable { var title: String } extension FifthOnboardingModel { - static let titles: [FifthOnboardingModel] = [FifthOnboardingModel(title: "배고플 때마다 양치하기"), - FifthOnboardingModel(title: "삶은 계란으로 대신하기"), - FifthOnboardingModel(title: "집에 간식 사두지 않기") + static let titles: [FifthOnboardingModel] = [ + FifthOnboardingModel(title: "배고플 때마다 양치하기"), + FifthOnboardingModel(title: "삶은 계란으로 대신하기"), + FifthOnboardingModel(title: "집에 간식 사두지 않기") ] } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/OnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/OnboardingViewModel.swift new file mode 100644 index 00000000..3043706f --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/OnboardingViewModel.swift @@ -0,0 +1,19 @@ +// +// OnboardingViewModel.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/13/24. +// + +import Foundation +import UIKit + +protocol OnboardingViewModel: ViewModel where Input == OnboardingViewModelInput, Output == OnboardingViewModelOutput {} + +struct OnboardingViewModelInput { + +} + +struct OnboardingViewModelOutput { + +} From e03ee71f40a7a3285db3a512543faf3f958a42dd Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Fri, 15 Mar 2024 00:21:18 +0900 Subject: [PATCH 02/16] =?UTF-8?q?[Add]=20#243=20-=20ViewModel=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModel/FifthOnboardingViewModel.swift | 8 ++++++++ .../FifthOnboardingViewModelImpl.swift | 8 ++++++++ .../ViewModel/FourthOnboardingViewModel.swift | 8 ++++++++ .../FourthOnboardingViewModelImpl.swift | 8 ++++++++ .../ViewModel/LogoOnboardingViewModel.swift | 8 ++++++++ .../LogoOnboardingViewModelImpl.swift | 8 ++++++++ .../ViewModel/OnboardingViewModel.swift | 19 ------------------- .../ViewModel/SecondOnboardingViewModel.swift | 8 ++++++++ .../SecondOnboardingViewModelImpl.swift | 8 ++++++++ .../ViewModel/ThirdOnboardingViewModel.swift | 8 ++++++++ .../ThirdOnboardingViewModelImpl.swift | 8 ++++++++ .../ViewModel/ValueOnboardingViewModel.swift | 8 ++++++++ .../ValueOnboardingViewModelImpl.swift | 8 ++++++++ 13 files changed, 96 insertions(+), 19 deletions(-) create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModel.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift delete mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/OnboardingViewModel.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModel.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift new file mode 100644 index 00000000..b6c724d1 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift @@ -0,0 +1,8 @@ +// +// FifthOnboardingViewModel.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift new file mode 100644 index 00000000..47b89506 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift @@ -0,0 +1,8 @@ +// +// FifthOnboardingViewModelImpl.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift new file mode 100644 index 00000000..49727c40 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift @@ -0,0 +1,8 @@ +// +// FourthOnboardingViewModel.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift new file mode 100644 index 00000000..e9c9f588 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift @@ -0,0 +1,8 @@ +// +// FourthOnboardingViewModelImpl.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModel.swift new file mode 100644 index 00000000..1458a907 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModel.swift @@ -0,0 +1,8 @@ +// +// LogoOnboardingViewModel.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift new file mode 100644 index 00000000..4c46d364 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift @@ -0,0 +1,8 @@ +// +// LogoOnboardingViewModelImpl.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/OnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/OnboardingViewModel.swift deleted file mode 100644 index 3043706f..00000000 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/OnboardingViewModel.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// OnboardingViewModel.swift -// iOS-NOTTODO -// -// Created by 강윤서 on 3/13/24. -// - -import Foundation -import UIKit - -protocol OnboardingViewModel: ViewModel where Input == OnboardingViewModelInput, Output == OnboardingViewModelOutput {} - -struct OnboardingViewModelInput { - -} - -struct OnboardingViewModelOutput { - -} diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift new file mode 100644 index 00000000..62730c49 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift @@ -0,0 +1,8 @@ +// +// SecondOnboardingViewModel.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift new file mode 100644 index 00000000..92c3f331 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift @@ -0,0 +1,8 @@ +// +// SecondOnboardingViewModelImpl.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift new file mode 100644 index 00000000..d1a9a698 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift @@ -0,0 +1,8 @@ +// +// ThirdOnboardingViewModel.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift new file mode 100644 index 00000000..86b92c2e --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift @@ -0,0 +1,8 @@ +// +// ThirdOnboardingViewModelImpl.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModel.swift new file mode 100644 index 00000000..e70f4393 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModel.swift @@ -0,0 +1,8 @@ +// +// ValueOnboardingViewModel.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift new file mode 100644 index 00000000..45801fca --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift @@ -0,0 +1,8 @@ +// +// ValueOnboardingViewModelImpl.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/14/24. +// + +import Foundation From 46e9041d237aad13e6167838c382b6f1fc289146 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Fri, 15 Mar 2024 00:23:17 +0900 Subject: [PATCH 03/16] =?UTF-8?q?[Feat]=20#243=20-=20LogoOnboardingView=20?= =?UTF-8?q?MVVM=20+=20Combine=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iOS-NOTTODO.xcodeproj/project.pbxproj | 144 ++++++++---------- .../Factory/ViewControllerFactory.swift | 3 +- .../LogoOnboardingViewController.swift | 21 ++- .../ViewModel/LogoOnboardingViewModel.swift | 10 +- .../LogoOnboardingViewModelImpl.swift | 22 ++- 5 files changed, 115 insertions(+), 85 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj index 4a4affef..72046972 100644 --- a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj +++ b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj @@ -35,7 +35,6 @@ 0982DE5829AE40FB00D933D2 /* UITabBar+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0982DE5729AE40FB00D933D2 /* UITabBar+.swift */; }; 0982DE5A29AE5E6000D933D2 /* CompositionalLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0982DE5929AE5E6000D933D2 /* CompositionalLayout.swift */; }; 0987C8402B9DD4DC007EE8DE /* MissionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0987C83F2B9DD242007EE8DE /* MissionService.swift */; }; - 098904292B81AF3E004AAD3C /* API_KEY.plist in Resources */ = {isa = PBXBuildFile; fileRef = 098904282B81AF3E004AAD3C /* API_KEY.plist */; }; 098904302B81BB3A004AAD3C /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0989042F2B81BB3A004AAD3C /* Coordinator.swift */; }; 098904322B81BB43004AAD3C /* CoordinatorDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 098904312B81BB43004AAD3C /* CoordinatorDelegate.swift */; }; 098904352B81BB85004AAD3C /* CoordinatorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 098904342B81BB85004AAD3C /* CoordinatorType.swift */; }; @@ -114,6 +113,7 @@ 3B14A13F29A6FCB300F92897 /* UIStackView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B14A13E29A6FCB300F92897 /* UIStackView+.swift */; }; 3B14A14129A6FDA900F92897 /* UILabel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B14A14029A6FDA900F92897 /* UILabel+.swift */; }; 3B14A14329A6FEE400F92897 /* UITextField+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B14A14229A6FEE400F92897 /* UITextField+.swift */; }; + 3B2A0BFB2BA34463003A7F1D /* API_KEY.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B2A0BFA2BA34463003A7F1D /* API_KEY.plist */; }; 3B2B59442AEB814B00B4619A /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 3B2B59432AEB814B00B4619A /* FirebaseMessaging */; }; 3B37AE2929C8821600AB7587 /* GoalCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B37AE2829C8821600AB7587 /* GoalCollectionViewCell.swift */; }; 3B37AE2B29C8904800AB7587 /* RecommendKeywordCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B37AE2A29C8904800AB7587 /* RecommendKeywordCollectionViewCell.swift */; }; @@ -135,8 +135,19 @@ 3B710A5C2A62D4AB00E95620 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 3B710A5B2A62D4AB00E95620 /* Settings.bundle */; }; 3B80B5D52B7F304D00697250 /* adjust+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80B5D42B7F304D00697250 /* adjust+.swift */; }; 3B80B5D72B7F30E200697250 /* Numbers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80B5D62B7F30E200697250 /* Numbers.swift */; }; - 3B877D622BA195C40002DFCB /* OnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B877D612BA195C40002DFCB /* OnboardingViewModel.swift */; }; 3B877D642BA1965F0002DFCB /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B877D632BA1965F0002DFCB /* ViewModel.swift */; }; + 3B87A4642BA32624005604C8 /* ValueOnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A4632BA32624005604C8 /* ValueOnboardingViewModel.swift */; }; + 3B87A4662BA3262F005604C8 /* LogoOnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A4652BA3262F005604C8 /* LogoOnboardingViewModel.swift */; }; + 3B87A4682BA3263C005604C8 /* SecondOnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A4672BA3263C005604C8 /* SecondOnboardingViewModel.swift */; }; + 3B87A46A2BA32646005604C8 /* ThirdOnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A4692BA32646005604C8 /* ThirdOnboardingViewModel.swift */; }; + 3B87A46C2BA32652005604C8 /* FourthOnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A46B2BA32652005604C8 /* FourthOnboardingViewModel.swift */; }; + 3B87A46E2BA3265B005604C8 /* FifthOnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A46D2BA3265B005604C8 /* FifthOnboardingViewModel.swift */; }; + 3B87A4702BA3266F005604C8 /* ValueOnboardingViewModelImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A46F2BA3266F005604C8 /* ValueOnboardingViewModelImpl.swift */; }; + 3B87A4722BA3267D005604C8 /* LogoOnboardingViewModelImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A4712BA3267D005604C8 /* LogoOnboardingViewModelImpl.swift */; }; + 3B87A4742BA32688005604C8 /* SecondOnboardingViewModelImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A4732BA32688005604C8 /* SecondOnboardingViewModelImpl.swift */; }; + 3B87A4762BA32693005604C8 /* ThirdOnboardingViewModelImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A4752BA32693005604C8 /* ThirdOnboardingViewModelImpl.swift */; }; + 3B87A4782BA3269E005604C8 /* FourthOnboardingViewModelImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A4772BA3269E005604C8 /* FourthOnboardingViewModelImpl.swift */; }; + 3B87A47A2BA326A9005604C8 /* FifthOnboardingViewModelImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B87A4792BA326A9005604C8 /* FifthOnboardingViewModelImpl.swift */; }; 3B892ABB2A2FBD4C00A316BC /* RecommendSituationResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B892ABA2A2FBD4C00A316BC /* RecommendSituationResponseDTO.swift */; }; 3B9532F42A284CC1006510F8 /* ModalProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B9532F32A284CC1006510F8 /* ModalProtocol.swift */; }; 3BBB6C8F2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BBB6C8E2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift */; }; @@ -145,21 +156,14 @@ 3BC1A27429C9AF500088376B /* MissionHistoryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC1A27329C9AF500088376B /* MissionHistoryCollectionViewCell.swift */; }; 3BC1A27929C9BE6C0088376B /* AddMissionFooterCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC1A27829C9BE6C0088376B /* AddMissionFooterCollectionReusableView.swift */; }; 3BD3B5C829B8F82C00D3575B /* AddMissionTextFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BD3B5C729B8F82C00D3575B /* AddMissionTextFieldView.swift */; }; + 3BE1FDFF2BA31795005EF562 /* KakaoSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 3BE1FDFE2BA31795005EF562 /* KakaoSDK */; }; + 3BE1FE012BA31795005EF562 /* KakaoSDKAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 3BE1FE002BA31795005EF562 /* KakaoSDKAuth */; }; 3BEEBE972A4B048A0081C936 /* NottodoToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEEBE962A4B048A0081C936 /* NottodoToastView.swift */; }; 6C049A312A595C670085E40B /* logo.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 6C049A302A595C670085E40B /* logo.mp4 */; }; 6C16015829C40112005AE3F5 /* AuthButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C16015729C40112005AE3F5 /* AuthButtonView.swift */; }; 6C16015C29C56DBA005AE3F5 /* MyInfoAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C16015B29C56DBA005AE3F5 /* MyInfoAccountViewController.swift */; }; 6C16016229C59EFD005AE3F5 /* MyInfoAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C16016129C59EFD005AE3F5 /* MyInfoAccountModel.swift */; }; 6C16016429C5E37D005AE3F5 /* MyInfoAccountStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C16016329C5E37D005AE3F5 /* MyInfoAccountStackView.swift */; }; - 6C44127129A35A1000313C3F /* KakaoSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6C44127029A35A1000313C3F /* KakaoSDK */; }; - 6C44127329A35A1000313C3F /* KakaoSDKAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 6C44127229A35A1000313C3F /* KakaoSDKAuth */; }; - 6C44127529A35A1000313C3F /* KakaoSDKCommon in Frameworks */ = {isa = PBXBuildFile; productRef = 6C44127429A35A1000313C3F /* KakaoSDKCommon */; }; - 6C44127729A35A1000313C3F /* KakaoSDKNavi in Frameworks */ = {isa = PBXBuildFile; productRef = 6C44127629A35A1000313C3F /* KakaoSDKNavi */; }; - 6C44127929A35A1000313C3F /* KakaoSDKShare in Frameworks */ = {isa = PBXBuildFile; productRef = 6C44127829A35A1000313C3F /* KakaoSDKShare */; }; - 6C44127B29A35A1000313C3F /* KakaoSDKStory in Frameworks */ = {isa = PBXBuildFile; productRef = 6C44127A29A35A1000313C3F /* KakaoSDKStory */; }; - 6C44127D29A35A1000313C3F /* KakaoSDKTalk in Frameworks */ = {isa = PBXBuildFile; productRef = 6C44127C29A35A1000313C3F /* KakaoSDKTalk */; }; - 6C44127F29A35A1000313C3F /* KakaoSDKTemplate in Frameworks */ = {isa = PBXBuildFile; productRef = 6C44127E29A35A1000313C3F /* KakaoSDKTemplate */; }; - 6C44128129A35A1000313C3F /* KakaoSDKUser in Frameworks */ = {isa = PBXBuildFile; productRef = 6C44128029A35A1000313C3F /* KakaoSDKUser */; }; 6C9628A72A22208F003ADE25 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 6C9628A62A22208F003ADE25 /* Lottie */; }; 6C9628A92A22209E003ADE25 /* LogoOnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C9628A82A22209E003ADE25 /* LogoOnboardingViewController.swift */; }; 6CA208232A18FE78001C4247 /* RecommendAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CA208222A18FE78001C4247 /* RecommendAPI.swift */; }; @@ -218,7 +222,6 @@ 0982DE5729AE40FB00D933D2 /* UITabBar+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITabBar+.swift"; sourceTree = ""; }; 0982DE5929AE5E6000D933D2 /* CompositionalLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionalLayout.swift; sourceTree = ""; }; 0987C83F2B9DD242007EE8DE /* MissionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MissionService.swift; sourceTree = ""; }; - 098904282B81AF3E004AAD3C /* API_KEY.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = API_KEY.plist; path = ../../../../Desktop/API_KEY.plist; sourceTree = ""; }; 0989042F2B81BB3A004AAD3C /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = ""; }; 098904312B81BB43004AAD3C /* CoordinatorDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoordinatorDelegate.swift; sourceTree = ""; }; 098904342B81BB85004AAD3C /* CoordinatorType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoordinatorType.swift; sourceTree = ""; }; @@ -294,6 +297,7 @@ 3B14A13E29A6FCB300F92897 /* UIStackView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+.swift"; sourceTree = ""; }; 3B14A14029A6FDA900F92897 /* UILabel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+.swift"; sourceTree = ""; }; 3B14A14229A6FEE400F92897 /* UITextField+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextField+.swift"; sourceTree = ""; }; + 3B2A0BFA2BA34463003A7F1D /* API_KEY.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = API_KEY.plist; path = ../../../../../../Desktop/API_KEY.plist; sourceTree = ""; }; 3B37AE2829C8821600AB7587 /* GoalCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoalCollectionViewCell.swift; sourceTree = ""; }; 3B37AE2A29C8904800AB7587 /* RecommendKeywordCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendKeywordCollectionViewCell.swift; sourceTree = ""; }; 3B3EF2F72AF35C90001F79BC /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; @@ -314,8 +318,19 @@ 3B710A5B2A62D4AB00E95620 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 3B80B5D42B7F304D00697250 /* adjust+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "adjust+.swift"; sourceTree = ""; }; 3B80B5D62B7F30E200697250 /* Numbers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Numbers.swift; sourceTree = ""; }; - 3B877D612BA195C40002DFCB /* OnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewModel.swift; sourceTree = ""; }; 3B877D632BA1965F0002DFCB /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = ""; }; + 3B87A4632BA32624005604C8 /* ValueOnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValueOnboardingViewModel.swift; sourceTree = ""; }; + 3B87A4652BA3262F005604C8 /* LogoOnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoOnboardingViewModel.swift; sourceTree = ""; }; + 3B87A4672BA3263C005604C8 /* SecondOnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondOnboardingViewModel.swift; sourceTree = ""; }; + 3B87A4692BA32646005604C8 /* ThirdOnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdOnboardingViewModel.swift; sourceTree = ""; }; + 3B87A46B2BA32652005604C8 /* FourthOnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FourthOnboardingViewModel.swift; sourceTree = ""; }; + 3B87A46D2BA3265B005604C8 /* FifthOnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FifthOnboardingViewModel.swift; sourceTree = ""; }; + 3B87A46F2BA3266F005604C8 /* ValueOnboardingViewModelImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValueOnboardingViewModelImpl.swift; sourceTree = ""; }; + 3B87A4712BA3267D005604C8 /* LogoOnboardingViewModelImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoOnboardingViewModelImpl.swift; sourceTree = ""; }; + 3B87A4732BA32688005604C8 /* SecondOnboardingViewModelImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondOnboardingViewModelImpl.swift; sourceTree = ""; }; + 3B87A4752BA32693005604C8 /* ThirdOnboardingViewModelImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdOnboardingViewModelImpl.swift; sourceTree = ""; }; + 3B87A4772BA3269E005604C8 /* FourthOnboardingViewModelImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FourthOnboardingViewModelImpl.swift; sourceTree = ""; }; + 3B87A4792BA326A9005604C8 /* FifthOnboardingViewModelImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FifthOnboardingViewModelImpl.swift; sourceTree = ""; }; 3B892ABA2A2FBD4C00A316BC /* RecommendSituationResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendSituationResponseDTO.swift; sourceTree = ""; }; 3B9532F32A284CC1006510F8 /* ModalProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalProtocol.swift; sourceTree = ""; }; 3BBB6C8E2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewLeftAlignLayout.swift; sourceTree = ""; }; @@ -366,23 +381,16 @@ buildActionMask = 2147483647; files = ( 3B146DA1299D0A7A00B17B62 /* SnapKit in Frameworks */, + 3BE1FDFF2BA31795005EF562 /* KakaoSDK in Frameworks */, 6CA2082C2A19122A001C4247 /* Kingfisher in Frameworks */, - 6C44127929A35A1000313C3F /* KakaoSDKShare in Frameworks */, - 6C44127B29A35A1000313C3F /* KakaoSDKStory in Frameworks */, 6C9628A72A22208F003ADE25 /* Lottie in Frameworks */, - 6C44127F29A35A1000313C3F /* KakaoSDKTemplate in Frameworks */, - 6C44127129A35A1000313C3F /* KakaoSDK in Frameworks */, 3B146DA4299D0A8600B17B62 /* Then in Frameworks */, 3B146DA7299D0AA300B17B62 /* Moya in Frameworks */, + 3BE1FE012BA31795005EF562 /* KakaoSDKAuth in Frameworks */, 155E45662B5FF089008628E7 /* FirebaseRemoteConfig in Frameworks */, 3B2B59442AEB814B00B4619A /* FirebaseMessaging in Frameworks */, - 6C44127729A35A1000313C3F /* KakaoSDKNavi in Frameworks */, - 6C44128129A35A1000313C3F /* KakaoSDKUser in Frameworks */, - 6C44127D29A35A1000313C3F /* KakaoSDKTalk in Frameworks */, - 6C44127529A35A1000313C3F /* KakaoSDKCommon in Frameworks */, 09C8602D2AB14B4800C4F4B1 /* FSCalendar in Frameworks */, 0943A9F52A531D0000614761 /* Amplitude in Frameworks */, - 6C44127329A35A1000313C3F /* KakaoSDKAuth in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -893,7 +901,7 @@ 3B027AA6299C359900BEB65C /* Resource */ = { isa = PBXGroup; children = ( - 098904282B81AF3E004AAD3C /* API_KEY.plist */, + 3B2A0BFA2BA34463003A7F1D /* API_KEY.plist */, 3B3EF2F72AF35C90001F79BC /* GoogleService-Info.plist */, 3B027A85299C31B600BEB65C /* Info.plist */, 3B027AAA299C35D000BEB65C /* Assets */, @@ -1028,7 +1036,18 @@ 3B877D602BA195A80002DFCB /* ViewModel */ = { isa = PBXGroup; children = ( - 3B877D612BA195C40002DFCB /* OnboardingViewModel.swift */, + 3B87A4632BA32624005604C8 /* ValueOnboardingViewModel.swift */, + 3B87A4652BA3262F005604C8 /* LogoOnboardingViewModel.swift */, + 3B87A4672BA3263C005604C8 /* SecondOnboardingViewModel.swift */, + 3B87A4692BA32646005604C8 /* ThirdOnboardingViewModel.swift */, + 3B87A46B2BA32652005604C8 /* FourthOnboardingViewModel.swift */, + 3B87A46D2BA3265B005604C8 /* FifthOnboardingViewModel.swift */, + 3B87A46F2BA3266F005604C8 /* ValueOnboardingViewModelImpl.swift */, + 3B87A4712BA3267D005604C8 /* LogoOnboardingViewModelImpl.swift */, + 3B87A4732BA32688005604C8 /* SecondOnboardingViewModelImpl.swift */, + 3B87A4752BA32693005604C8 /* ThirdOnboardingViewModelImpl.swift */, + 3B87A4772BA3269E005604C8 /* FourthOnboardingViewModelImpl.swift */, + 3B87A4792BA326A9005604C8 /* FifthOnboardingViewModelImpl.swift */, ); path = ViewModel; sourceTree = ""; @@ -1271,21 +1290,14 @@ 3B146DA0299D0A7A00B17B62 /* SnapKit */, 3B146DA3299D0A8600B17B62 /* Then */, 3B146DA6299D0AA300B17B62 /* Moya */, - 6C44127029A35A1000313C3F /* KakaoSDK */, - 6C44127229A35A1000313C3F /* KakaoSDKAuth */, - 6C44127429A35A1000313C3F /* KakaoSDKCommon */, - 6C44127629A35A1000313C3F /* KakaoSDKNavi */, - 6C44127829A35A1000313C3F /* KakaoSDKShare */, - 6C44127A29A35A1000313C3F /* KakaoSDKStory */, - 6C44127C29A35A1000313C3F /* KakaoSDKTalk */, - 6C44127E29A35A1000313C3F /* KakaoSDKTemplate */, - 6C44128029A35A1000313C3F /* KakaoSDKUser */, 6CA2082B2A19122A001C4247 /* Kingfisher */, 6C9628A62A22208F003ADE25 /* Lottie */, 0943A9F42A531D0000614761 /* Amplitude */, 09C8602C2AB14B4800C4F4B1 /* FSCalendar */, 3B2B59432AEB814B00B4619A /* FirebaseMessaging */, 155E45652B5FF089008628E7 /* FirebaseRemoteConfig */, + 3BE1FDFE2BA31795005EF562 /* KakaoSDK */, + 3BE1FE002BA31795005EF562 /* KakaoSDKAuth */, ); productName = "iOS-NOTTODO"; productReference = 3B027A74299C31B500BEB65C /* iOS-NOTTODO.app */; @@ -1319,12 +1331,12 @@ 3B146D9F299D0A7A00B17B62 /* XCRemoteSwiftPackageReference "SnapKit" */, 3B146DA2299D0A8600B17B62 /* XCRemoteSwiftPackageReference "Then" */, 3B146DA5299D0AA300B17B62 /* XCRemoteSwiftPackageReference "Moya" */, - 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */, 6CA2082A2A19122A001C4247 /* XCRemoteSwiftPackageReference "Kingfisher" */, 6C9628A52A22208F003ADE25 /* XCRemoteSwiftPackageReference "lottie-ios" */, 0943A9F32A531D0000614761 /* XCRemoteSwiftPackageReference "Amplitude-iOS" */, 09C8602B2AB14B4700C4F4B1 /* XCRemoteSwiftPackageReference "FSCalendar" */, 3B2B59422AEB814B00B4619A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, + 3BE1FDFD2BA31795005EF562 /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */, ); productRefGroup = 3B027A75299C31B500BEB65C /* Products */; projectDirPath = ""; @@ -1347,7 +1359,7 @@ 3B710A5C2A62D4AB00E95620 /* Settings.bundle in Resources */, 3B027A84299C31B600BEB65C /* LaunchScreen.storyboard in Resources */, 6CC54C1A2A28C3AE00AAD76D /* value.json in Resources */, - 098904292B81AF3E004AAD3C /* API_KEY.plist in Resources */, + 3B2A0BFB2BA34463003A7F1D /* API_KEY.plist in Resources */, 3B3EF2F82AF35C90001F79BC /* GoogleService-Info.plist in Resources */, 6C049A312A595C670085E40B /* logo.mp4 in Resources */, 3B027A81299C31B600BEB65C /* Assets.xcassets in Resources */, @@ -1385,18 +1397,20 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3B87A4662BA3262F005604C8 /* LogoOnboardingViewModel.swift in Sources */, 3B03D0D62B0F15AA00302872 /* NotificationDialogViewController.swift in Sources */, 09F6719729CC81B500708725 /* DetailAchievementCollectionViewCell.swift in Sources */, 0960C0D62A38BC8100A3D8DB /* DefaultKeys.swift in Sources */, 3B14A14129A6FDA900F92897 /* UILabel+.swift in Sources */, + 3B87A4682BA3263C005604C8 /* SecondOnboardingViewModel.swift in Sources */, 09A146652A1964B500DDC308 /* AddAnotherDayResponseDTO.swift in Sources */, 3B027A7C299C31B500BEB65C /* AuthViewController.swift in Sources */, 098904382B81BC16004AAD3C /* AppCoordinator.swift in Sources */, 6C16016229C59EFD005AE3F5 /* MyInfoAccountModel.swift in Sources */, 3B027A92299C33FE00BEB65C /* UIColor+.swift in Sources */, - 3B877D622BA195C40002DFCB /* OnboardingViewModel.swift in Sources */, 092C09B52A484DD900E9B06B /* HomeDeleteViewController.swift in Sources */, 3B027AA4299C357000BEB65C /* MyInfoViewController.swift in Sources */, + 3B87A4762BA32693005604C8 /* ThirdOnboardingViewModelImpl.swift in Sources */, 0989043B2B81BCFA004AAD3C /* AppCoordinatorImpl.swift in Sources */, 097568362A2FEF630001EC46 /* String+.swift in Sources */, 6CA2B7BB2A222D2300A9E549 /* ValueOnboardingViewController.swift in Sources */, @@ -1411,6 +1425,7 @@ 098BFD5929B7999E008E80F9 /* MyProfileCollectionViewCell.swift in Sources */, 3B5F8F7A29BF8E8D0063A7F8 /* AddMissionProtocol.swift in Sources */, 09F6718C29CB4AB700708725 /* SubOnboardingCollectionViewCell.swift in Sources */, + 3B87A4702BA3266F005604C8 /* ValueOnboardingViewModelImpl.swift in Sources */, 0921611D2A57D0920019CC8C /* AmplitudeAnalyticsService.swift in Sources */, 3B027A96299C340C00BEB65C /* UIImage+.swift in Sources */, 0921611F2A57D7BF0019CC8C /* AnalyticsEvent.swift in Sources */, @@ -1426,6 +1441,8 @@ 3B14A14329A6FEE400F92897 /* UITextField+.swift in Sources */, 098904482B81C197004AAD3C /* AchieveCoordinator.swift in Sources */, 09022D4629C44BC300DE6E49 /* MissionCalendarCell.swift in Sources */, + 3B87A4742BA32688005604C8 /* SecondOnboardingViewModelImpl.swift in Sources */, + 3B87A4722BA3267D005604C8 /* LogoOnboardingViewModelImpl.swift in Sources */, 6CA2083A2A195906001C4247 /* AuthResponseDTO.swift in Sources */, 09582B4B29BDE37C00EF3207 /* DetailFooterReusableView.swift in Sources */, 09CF56042B09F23800526C8C /* HomeDataSource.swift in Sources */, @@ -1437,6 +1454,7 @@ 092E04B129BD9C86008A5892 /* MissionDetailCollectionViewCell.swift in Sources */, 6CF4706D29A739D9008D145C /* RecommendViewController.swift in Sources */, 3BC1A27429C9AF500088376B /* MissionHistoryCollectionViewCell.swift in Sources */, + 3B87A4642BA32624005604C8 /* ValueOnboardingViewModel.swift in Sources */, 3B027A9E299C34DA00BEB65C /* HomeViewController.swift in Sources */, 09F6719029CB6AB400708725 /* OnboardingFooterView.swift in Sources */, 3B482FA9299EB95400BCF424 /* UIScreen+.swift in Sources */, @@ -1451,6 +1469,7 @@ 0960C0D42A38BC6500A3D8DB /* KeychainUtil.swift in Sources */, 3B03D0D82B0F5EF300302872 /* CGSize+.swift in Sources */, 098904502B81C21D004AAD3C /* AchieveCoordinatorImpl.swift in Sources */, + 3B87A46E2BA3265B005604C8 /* FifthOnboardingViewModel.swift in Sources */, 6CA208302A1925EE001C4247 /* RecommendActionResponseDTO.swift in Sources */, 098A23A22B833C6700265955 /* AuthCoordinator.swift in Sources */, 09F6718629CB26E400708725 /* OnboardingHeaderView.swift in Sources */, @@ -1458,6 +1477,7 @@ 155E456D2B62B1A1008628E7 /* UpdateCheckViewController.swift in Sources */, 098904302B81BB3A004AAD3C /* Coordinator.swift in Sources */, 3B14A13D29A6FBD300F92897 /* UIView+.swift in Sources */, + 3B87A46A2BA32646005604C8 /* ThirdOnboardingViewModel.swift in Sources */, 09F6719529CBFCD200708725 /* GradientView.swift in Sources */, 09CF56022B09E98A00526C8C /* DetailAchieveHeaderView.swift in Sources */, 3B4E12F82A27C12F001D1EC1 /* WithdrawModalView.swift in Sources */, @@ -1483,10 +1503,12 @@ 3BC1A27229C9AF310088376B /* MissionHistoryModels.swift in Sources */, 6CD4F8BA29AA493600CCC740 /* RecommendActionHeaderView.swift in Sources */, 0930DE6229B80550007958DE /* MissionDetailViewController.swift in Sources */, + 3B87A46C2BA32652005604C8 /* FourthOnboardingViewModel.swift in Sources */, 0989044C2B81C210004AAD3C /* HomecoordinatorImpl.swift in Sources */, 3B14A13F29A6FCB300F92897 /* UIStackView+.swift in Sources */, 6CD4F8BC29AA494300CCC740 /* RecommendActionFooterView.swift in Sources */, 6CD4F8BE29AA495900CCC740 /* RecommendActionCollectionViewCell.swift in Sources */, + 3B87A4782BA3269E005604C8 /* FourthOnboardingViewModelImpl.swift in Sources */, 6CF4707429A73D4C008D145C /* RecommendCollectionViewCell.swift in Sources */, 3BBB6C8F2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift in Sources */, 09A1465F2A192C4900DDC308 /* WeekMissionResponseDTO.swift in Sources */, @@ -1523,6 +1545,7 @@ 098A23A42B833F0300265955 /* AuthCoordinatorImpl.swift in Sources */, 098BFD5D29B79CE3008E80F9 /* InfoCollectionViewCell.swift in Sources */, 3B0CBA222A45FC170004F2DB /* UpdateMissionResponseDTO.swift in Sources */, + 3B87A47A2BA326A9005604C8 /* FifthOnboardingViewModelImpl.swift in Sources */, 092C09B72A48596500E9B06B /* DeleteModalView.swift in Sources */, 155E45692B5FF2EE008628E7 /* FirebaseUtil.swift in Sources */, 098904402B81BFAF004AAD3C /* ViewControllerFactory.swift in Sources */, @@ -1814,12 +1837,12 @@ minimumVersion = 10.0.0; }; }; - 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */ = { + 3BE1FDFD2BA31795005EF562 /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/kakao/kakao-ios-sdk"; requirement = { - branch = master; - kind = branch; + kind = upToNextMajorVersion; + minimumVersion = 2.21.0; }; }; 6C9628A52A22208F003ADE25 /* XCRemoteSwiftPackageReference "lottie-ios" */ = { @@ -1876,51 +1899,16 @@ package = 3B2B59422AEB814B00B4619A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseMessaging; }; - 6C44127029A35A1000313C3F /* KakaoSDK */ = { + 3BE1FDFE2BA31795005EF562 /* KakaoSDK */ = { isa = XCSwiftPackageProductDependency; - package = 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; + package = 3BE1FDFD2BA31795005EF562 /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; productName = KakaoSDK; }; - 6C44127229A35A1000313C3F /* KakaoSDKAuth */ = { + 3BE1FE002BA31795005EF562 /* KakaoSDKAuth */ = { isa = XCSwiftPackageProductDependency; - package = 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; + package = 3BE1FDFD2BA31795005EF562 /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; productName = KakaoSDKAuth; }; - 6C44127429A35A1000313C3F /* KakaoSDKCommon */ = { - isa = XCSwiftPackageProductDependency; - package = 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; - productName = KakaoSDKCommon; - }; - 6C44127629A35A1000313C3F /* KakaoSDKNavi */ = { - isa = XCSwiftPackageProductDependency; - package = 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; - productName = KakaoSDKNavi; - }; - 6C44127829A35A1000313C3F /* KakaoSDKShare */ = { - isa = XCSwiftPackageProductDependency; - package = 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; - productName = KakaoSDKShare; - }; - 6C44127A29A35A1000313C3F /* KakaoSDKStory */ = { - isa = XCSwiftPackageProductDependency; - package = 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; - productName = KakaoSDKStory; - }; - 6C44127C29A35A1000313C3F /* KakaoSDKTalk */ = { - isa = XCSwiftPackageProductDependency; - package = 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; - productName = KakaoSDKTalk; - }; - 6C44127E29A35A1000313C3F /* KakaoSDKTemplate */ = { - isa = XCSwiftPackageProductDependency; - package = 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; - productName = KakaoSDKTemplate; - }; - 6C44128029A35A1000313C3F /* KakaoSDKUser */ = { - isa = XCSwiftPackageProductDependency; - package = 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; - productName = KakaoSDKUser; - }; 6C9628A62A22208F003ADE25 /* Lottie */ = { isa = XCSwiftPackageProductDependency; package = 6C9628A52A22208F003ADE25 /* XCRemoteSwiftPackageReference "lottie-ios" */; diff --git a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift index 94f5cc40..0bfa6b04 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift @@ -68,7 +68,8 @@ extension ViewControllerFactoryImpl { return viewController } func makeLogoOnboardingViewController(coordinator: AuthCoordinator) -> LogoOnboardingViewController { - let viewController = LogoOnboardingViewController(coordinator: coordinator) + let viewModel = LogoOnboardingViewModelImpl(coodinator: coordinator) + let viewController = LogoOnboardingViewController(viewModel: viewModel) return viewController } func makeSecondOnboardingViewController(coordinator: AuthCoordinator) -> SecondOnboardingViewController { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift index ac7e72e4..1931ff2f 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift @@ -7,15 +7,20 @@ import UIKit import AVFoundation +import Combine final class LogoOnboardingViewController: UIViewController { // MARK: - Properties private lazy var safeArea = self.view.safeAreaLayoutGuide - private weak var coordinator: AuthCoordinator? private var player: AVPlayer? + private let viewModel: any LogoOnboardingViewModel + private var cancelBag = Set() + + private let startButtonDidTapped = PassthroughSubject() + // MARK: - UI Components private let animationView = UIImageView() @@ -23,8 +28,8 @@ final class LogoOnboardingViewController: UIViewController { // MARK: - init - init(coordinator: AuthCoordinator) { - self.coordinator = coordinator + init(viewModel: some LogoOnboardingViewModel) { + self.viewModel = viewModel super.init(nibName: nil, bundle: nil) } @@ -38,6 +43,7 @@ final class LogoOnboardingViewController: UIViewController { super.viewDidLoad() setUI() setLayout() + setBindings() } override func viewWillAppear(_ animated: Bool) { @@ -109,6 +115,13 @@ extension LogoOnboardingViewController { } } + private func setBindings() { + let input = LogoOnboardingViewModelInput( + startButtonTappedSubject: startButtonDidTapped + ) + _ = viewModel.transform(input: input) + } + @objc private func videoDidFinishPlaying(notification: NSNotification) { nextButton.isHidden = false @@ -117,6 +130,6 @@ extension LogoOnboardingViewController { @objc private func buttonTapped() { AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingStart) - coordinator?.showSecondOnboardingViewController() + startButtonDidTapped.send() } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModel.swift index 1458a907..8a10d8e8 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModel.swift @@ -5,4 +5,12 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +protocol LogoOnboardingViewModel: ViewModel where Input == LogoOnboardingViewModelInput, Output == LogoOnboardingViewModelOutput {} + +struct LogoOnboardingViewModelInput { + let startButtonTappedSubject: PassthroughSubject +} + +struct LogoOnboardingViewModelOutput {} diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift index 4c46d364..cf99f722 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift @@ -5,4 +5,24 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +final class LogoOnboardingViewModelImpl: LogoOnboardingViewModel { + + private weak var coodinator: AuthCoordinator? + private var cancelBag = Set() + + init(coodinator: AuthCoordinator) { + self.coodinator = coodinator + } + + func transform(input: LogoOnboardingViewModelInput) -> LogoOnboardingViewModelOutput { + input.startButtonTappedSubject + .sink { [weak self] _ in + self?.coodinator?.showSecondOnboardingViewController() + } + .store(in: &cancelBag) + + return LogoOnboardingViewModelOutput() + } +} From 7d287ba97efe76a85c932a52be22a984350932b9 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Fri, 15 Mar 2024 00:40:23 +0900 Subject: [PATCH 04/16] =?UTF-8?q?[Feat]=20#243=20-=20ValueOnboardingView?= =?UTF-8?q?=20MVVM=20+=20Combine=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Factory/ViewControllerFactory.swift | 3 ++- .../ValueOnboardingViewController.swift | 21 +++++++++++------ .../ViewModel/ValueOnboardingViewModel.swift | 10 +++++++- .../ValueOnboardingViewModelImpl.swift | 23 ++++++++++++++++++- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift index 0bfa6b04..a40d64a5 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift @@ -64,7 +64,8 @@ extension ViewControllerFactoryImpl { // onboarding extension ViewControllerFactoryImpl { func makeValueOnboardingViewController(coordinator: AuthCoordinator) -> ValueOnboardingViewController { - let viewController = ValueOnboardingViewController(coordinator: coordinator) + let viewModel = ValueOnboardingViewModelImpl(coordinator: coordinator) + let viewController = ValueOnboardingViewController(viewModel: viewModel) return viewController } func makeLogoOnboardingViewController(coordinator: AuthCoordinator) -> LogoOnboardingViewController { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ValueOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ValueOnboardingViewController.swift index 36f08add..8f441a39 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ValueOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ValueOnboardingViewController.swift @@ -7,13 +7,17 @@ import UIKit +import Combine import Lottie final class ValueOnboardingViewController: UIViewController { // MARK: - Properties - private weak var coordinator: AuthCoordinator? + private let viewModel: any ValueOnboardingViewModel + private var cancelBag = Set() + + private let endAnimationSubject = PassthroughSubject() // MARK: - UI Properties @@ -21,8 +25,8 @@ final class ValueOnboardingViewController: UIViewController { // MARK: - init - init(coordinator: AuthCoordinator) { - self.coordinator = coordinator + init(viewModel: some ValueOnboardingViewModel) { + self.viewModel = viewModel super.init(nibName: nil, bundle: nil) } @@ -35,8 +39,9 @@ final class ValueOnboardingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() playAnimation(named: "value") { [weak self] in - self?.pushToNextViewController() + self?.endAnimationSubject.send() } + setBindings() } deinit { @@ -49,7 +54,7 @@ final class ValueOnboardingViewController: UIViewController { extension ValueOnboardingViewController { - func playAnimation(named name: String, completion: @escaping () -> Void) { + private func playAnimation(named name: String, completion: @escaping () -> Void) { let animation = LottieAnimation.named(name) animationView.animation = animation @@ -65,7 +70,9 @@ extension ValueOnboardingViewController { } } - func pushToNextViewController() { - coordinator?.showLogoOnboardingViewController() + private func setBindings() { + let input = ValueOnboardingViewModelInput( + endAnimationSubject: endAnimationSubject) + _ = viewModel.transform(input: input) } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModel.swift index e70f4393..78ffacb3 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModel.swift @@ -5,4 +5,12 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +protocol ValueOnboardingViewModel: ViewModel where Input == ValueOnboardingViewModelInput, Output == ValueOnboardingViewModelOutput {} + +struct ValueOnboardingViewModelInput { + let endAnimationSubject: PassthroughSubject +} + +struct ValueOnboardingViewModelOutput { } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift index 45801fca..46910ce5 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift @@ -5,4 +5,25 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +final class ValueOnboardingViewModelImpl: ValueOnboardingViewModel { + + private weak var coordinator: AuthCoordinator? + private var cancelBag = Set() + + init(coordinator: AuthCoordinator) { + self.coordinator = coordinator + } + + func transform(input: ValueOnboardingViewModelInput) -> ValueOnboardingViewModelOutput { + input.endAnimationSubject + .sink { [weak self] _ in + self?.coordinator?.showLogoOnboardingViewController() + } + .store(in: &cancelBag) + + return ValueOnboardingViewModelOutput() + } + +} From dc43e1fa31b38b710f5977732dd816113bf0688b Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Fri, 15 Mar 2024 01:10:15 +0900 Subject: [PATCH 05/16] =?UTF-8?q?[Feat]=20#243=20-=20secondOnboardingView?= =?UTF-8?q?=20MVVM=20+=20Combine=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Factory/ViewControllerFactory.swift | 3 ++- .../SecondOnboardingViewController.swift | 20 +++++++++++++---- .../ViewModel/SecondOnboardingViewModel.swift | 9 ++++++++ .../SecondOnboardingViewModelImpl.swift | 22 ++++++++++++++++++- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift index a40d64a5..550fe2c9 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift @@ -74,7 +74,8 @@ extension ViewControllerFactoryImpl { return viewController } func makeSecondOnboardingViewController(coordinator: AuthCoordinator) -> SecondOnboardingViewController { - let viewController = SecondOnboardingViewController(coordinator: coordinator) + let viewModel = SecondOnboardingViewModelImpl(coordinator: coordinator) + let viewController = SecondOnboardingViewController(viewModel: viewModel) return viewController } func makeThirdOnboardingViewController(coordinator: AuthCoordinator) -> ThirdOnboardingViewController { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift index 5cbb9d09..e557e8c5 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift @@ -7,6 +7,7 @@ import UIKit +import Combine import SnapKit import Then @@ -20,7 +21,11 @@ final class SecondOnboardingViewController: UIViewController { private let onboardingModel: [SecondOnboardingModel] = SecondOnboardingModel.titles private var dataSource: UICollectionViewDiffableDataSource! = nil private lazy var safeArea = self.view.safeAreaLayoutGuide - private weak var coordinator: AuthCoordinator? + + private let viewModel: any SecondOnboardingViewModel + private var cancelBag = Set() + + private let onbaordingCellTapped = PassthroughSubject() // MARK: - UI Components @@ -28,8 +33,8 @@ final class SecondOnboardingViewController: UIViewController { // MARK: - init - init(coordinator: AuthCoordinator) { - self.coordinator = coordinator + init(viewModel: some SecondOnboardingViewModel) { + self.viewModel = viewModel super.init(nibName: nil, bundle: nil) } @@ -47,6 +52,7 @@ final class SecondOnboardingViewController: UIViewController { setLayout() setupDataSource() reloadData() + setBindings() } } @@ -113,12 +119,18 @@ extension SecondOnboardingViewController { let layout = UICollectionViewCompositionalLayout(section: section) return layout } + + private func setBindings() { + let input = SecondOnboardingViewModelInput( + cellTapped: onbaordingCellTapped) + _ = viewModel.transform(input: input) + } } extension SecondOnboardingViewController: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext2(select: SecondOnboardingModel.titles[indexPath.row].title)) - coordinator?.showThirdOnboardingViewController() + self.onbaordingCellTapped.send(indexPath) } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift index 62730c49..d057fa41 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift @@ -5,4 +5,13 @@ // Created by 강윤서 on 3/14/24. // +import Combine import Foundation + +protocol SecondOnboardingViewModel: ViewModel where Input == SecondOnboardingViewModelInput, Output == SecondOnboardingViewModelOutput { } + +struct SecondOnboardingViewModelInput { + let cellTapped: PassthroughSubject +} + +struct SecondOnboardingViewModelOutput { } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift index 92c3f331..4921d4dd 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift @@ -5,4 +5,24 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +final class SecondOnboardingViewModelImpl: SecondOnboardingViewModel { + + private weak var coordinator: AuthCoordinator? + private var cancelBag = Set() + + init(coordinator: AuthCoordinator) { + self.coordinator = coordinator + } + + func transform(input: SecondOnboardingViewModelInput) -> SecondOnboardingViewModelOutput { + input.cellTapped + .sink { [weak self] _ in + guard let self else { return } + self.coordinator?.showThirdOnboardingViewController() + } + .store(in: &cancelBag) + return SecondOnboardingViewModelOutput() + } +} From 4e18840d92ea302135e6effba730e981cdfbafec Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Fri, 15 Mar 2024 01:10:48 +0900 Subject: [PATCH 06/16] =?UTF-8?q?[Fix]=20#243=20-=20guard=20let=20?= =?UTF-8?q?=EA=B5=AC=EB=AC=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift | 3 ++- .../Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift index cf99f722..65c918eb 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift @@ -19,7 +19,8 @@ final class LogoOnboardingViewModelImpl: LogoOnboardingViewModel { func transform(input: LogoOnboardingViewModelInput) -> LogoOnboardingViewModelOutput { input.startButtonTappedSubject .sink { [weak self] _ in - self?.coodinator?.showSecondOnboardingViewController() + guard let self else { return } + self.coodinator?.showSecondOnboardingViewController() } .store(in: &cancelBag) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift index 46910ce5..6f117a16 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ValueOnboardingViewModelImpl.swift @@ -19,7 +19,8 @@ final class ValueOnboardingViewModelImpl: ValueOnboardingViewModel { func transform(input: ValueOnboardingViewModelInput) -> ValueOnboardingViewModelOutput { input.endAnimationSubject .sink { [weak self] _ in - self?.coordinator?.showLogoOnboardingViewController() + guard let self else { return } + self.coordinator?.showLogoOnboardingViewController() } .store(in: &cancelBag) From 594ad4454b208432bf23f46b97bb201c851748a2 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Fri, 15 Mar 2024 01:26:57 +0900 Subject: [PATCH 07/16] =?UTF-8?q?[Feat]=20#243=20-=20ThirdOnboardingView?= =?UTF-8?q?=20MVVM=20+=20Combine=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Factory/ViewControllerFactory.swift | 3 ++- .../ThirdOnboardingViewController.swift | 24 ++++++++++++++----- .../ViewModel/ThirdOnboardingViewModel.swift | 10 +++++++- .../ThirdOnboardingViewModelImpl.swift | 23 +++++++++++++++++- 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift index 550fe2c9..d37a94f6 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift @@ -79,7 +79,8 @@ extension ViewControllerFactoryImpl { return viewController } func makeThirdOnboardingViewController(coordinator: AuthCoordinator) -> ThirdOnboardingViewController { - let viewController = ThirdOnboardingViewController(coordinator: coordinator) + let viewModel = ThirdOnboardingViewModelImpl(coordinator: coordinator) + let viewController = ThirdOnboardingViewController(viewModel: viewModel) return viewController } func makeFourthOnboardingViewController(coordinator: AuthCoordinator) -> FourthOnboardingViewController { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift index b798cca5..36096e8c 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift @@ -7,6 +7,7 @@ import UIKit +import Combine import SnapKit import Then @@ -22,7 +23,11 @@ final class ThirdOnboardingViewController: UIViewController { private var dataSource: UICollectionViewDiffableDataSource! = nil private lazy var safeArea = self.view.safeAreaLayoutGuide private var selectList: [String] = [] - private weak var coordinator: AuthCoordinator? + + private let viewModel: any ThirdOnboardingViewModel + private var cancelBag = Set() + + private let nextButtonDidTapped = PassthroughSubject() // MARK: - UI Components @@ -31,8 +36,9 @@ final class ThirdOnboardingViewController: UIViewController { private var isTapped: Bool = false // MARK: - init - init(coordinator: AuthCoordinator) { - self.coordinator = coordinator + + init(viewModel: some ThirdOnboardingViewModel) { + self.viewModel = viewModel super.init(nibName: nil, bundle: nil) } @@ -50,6 +56,7 @@ final class ThirdOnboardingViewController: UIViewController { setLayout() setupDataSource() reloadData() + setBindings() } } @@ -60,6 +67,7 @@ extension ThirdOnboardingViewController { collectionView.register(OnboardingCollectionViewCell.self, forCellWithReuseIdentifier: OnboardingCollectionViewCell.identifier) collectionView.register(OnboardingHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: OnboardingHeaderView.identifier) } + private func setUI() { view.backgroundColor = .ntdBlack @@ -141,14 +149,19 @@ extension ThirdOnboardingViewController { section.boundarySupplementaryItems = [header] return UICollectionViewCompositionalLayout(section: section) } + + private func setBindings() { + let input = ThirdOnboardingViewModelInput( + nextButtonDidTapped: nextButtonDidTapped) + _ = viewModel.transform(input: input) + } } extension ThirdOnboardingViewController { @objc private func buttonTapped() { - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext3(select: self.selectList)) - self.coordinator?.showFourthOnboardingViewController() + self.nextButtonDidTapped.send() } } @@ -171,7 +184,6 @@ extension ThirdOnboardingViewController: UICollectionViewDelegate { } self.isTapped = false updateButton(isTapped: self.isTapped) - } } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift index d1a9a698..4202b6af 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift @@ -5,4 +5,12 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +protocol ThirdOnboardingViewModel: ViewModel where Input == ThirdOnboardingViewModelInput, Output == ThirdOnboardingViewModelOutput {} + +struct ThirdOnboardingViewModelInput { + let nextButtonDidTapped: PassthroughSubject +} + +struct ThirdOnboardingViewModelOutput {} diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift index 86b92c2e..b469513e 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift @@ -5,4 +5,25 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +final class ThirdOnboardingViewModelImpl: ThirdOnboardingViewModel { + + private weak var coordinator: AuthCoordinator? + private var cancelBag = Set() + + init(coordinator: AuthCoordinator) { + self.coordinator = coordinator + } + + func transform(input: ThirdOnboardingViewModelInput) -> ThirdOnboardingViewModelOutput { + input.nextButtonDidTapped + .sink { [weak self] _ in + guard let self else { return } + self.coordinator?.showFourthOnboardingViewController() + } + .store(in: &cancelBag) + + return ThirdOnboardingViewModelOutput() + } +} From b6f026e184435cbe232b5853a7def5fafefa92b4 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Fri, 15 Mar 2024 01:35:31 +0900 Subject: [PATCH 08/16] =?UTF-8?q?[Feat]=20#243=20-=20FourthOnboardingView?= =?UTF-8?q?=20MVVM=20+=20Combine=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Factory/ViewControllerFactory.swift | 3 ++- .../FourthOnboardingViewController.swift | 23 +++++++++++++++---- .../ViewModel/FourthOnboardingViewModel.swift | 10 +++++++- .../FourthOnboardingViewModelImpl.swift | 22 +++++++++++++++++- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift index d37a94f6..b6aec976 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift @@ -84,7 +84,8 @@ extension ViewControllerFactoryImpl { return viewController } func makeFourthOnboardingViewController(coordinator: AuthCoordinator) -> FourthOnboardingViewController { - let viewController = FourthOnboardingViewController(coordinator: coordinator) + let viewModel = FourthOnboardingViewModelImpl(coordinator: coordinator) + let viewController = FourthOnboardingViewController(viewModel: viewModel) return viewController } func makeFifthOnboardingViewController(coordinator: AuthCoordinator) -> FifthOnboardingViewController { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift index 5da1868f..3de85e48 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift @@ -7,6 +7,7 @@ import UIKit +import Combine import SnapKit import Then @@ -20,7 +21,11 @@ final class FourthOnboardingViewController: UIViewController { private let onboardingModel: [FourthOnboardingModel] = FourthOnboardingModel.items private var dataSource: UICollectionViewDiffableDataSource! = nil private lazy var safeArea = self.view.safeAreaLayoutGuide - private weak var coordinator: AuthCoordinator? + + private let viewModel: any FourthOnboardingViewModel + private var cancelBag = Set() + + private let buttonDidTapped = PassthroughSubject() // MARK: - UI Components @@ -30,8 +35,8 @@ final class FourthOnboardingViewController: UIViewController { // MARK: - init - init(coordinator: AuthCoordinator) { - self.coordinator = coordinator + init(viewModel: some FourthOnboardingViewModel) { + self.viewModel = viewModel super.init(nibName: nil, bundle: nil) } @@ -49,6 +54,7 @@ final class FourthOnboardingViewController: UIViewController { setLayout() setupDataSource() reloadData() + setBindings() } } @@ -59,6 +65,7 @@ extension FourthOnboardingViewController { collectionView.register(SubOnboardingCollectionViewCell.self, forCellWithReuseIdentifier: SubOnboardingCollectionViewCell.identifier) collectionView.register(OnboardingHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: OnboardingHeaderView.identifier) } + private func setUI() { view.backgroundColor = .ntdBlack @@ -67,6 +74,7 @@ extension FourthOnboardingViewController { $0.bounces = false $0.isScrollEnabled = false } + nextButton.do { $0.configuration?.image = .splashBack $0.configuration?.title = I18N.fourthButton @@ -137,12 +145,19 @@ extension FourthOnboardingViewController { let layout = UICollectionViewCompositionalLayout(section: section) return layout } + + private func setBindings() { + let input = FourthOnboardingViewModelInput( + buttonDidTapped: buttonDidTapped + ) + _ = viewModel.transform(input: input) + } } extension FourthOnboardingViewController { @objc private func buttonTapped() { AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext4) - self.coordinator?.showFifthOnboardingViewController() + self.buttonDidTapped.send() } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift index 49727c40..4095aece 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift @@ -5,4 +5,12 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +protocol FourthOnboardingViewModel: ViewModel where Input == FourthOnboardingViewModelInput, Output == FourthOnboardingViewModelOutput {} + +struct FourthOnboardingViewModelInput { + let buttonDidTapped: PassthroughSubject +} + +struct FourthOnboardingViewModelOutput {} diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift index e9c9f588..4c56e66a 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift @@ -5,4 +5,24 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +final class FourthOnboardingViewModelImpl: FourthOnboardingViewModel { + + private weak var coordinator: AuthCoordinator? + private var cancelBag = Set() + + init(coordinator: AuthCoordinator) { + self.coordinator = coordinator + } + + func transform(input: FourthOnboardingViewModelInput) -> FourthOnboardingViewModelOutput { + input.buttonDidTapped + .sink { [weak self] _ in + guard let self else { return } + self.coordinator?.showFifthOnboardingViewController() + } + .store(in: &cancelBag) + return FourthOnboardingViewModelOutput() + } +} From 9f6df26a856dc2f0b6f49a4028a637ca6153164e Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Fri, 15 Mar 2024 01:44:17 +0900 Subject: [PATCH 09/16] =?UTF-8?q?[Feat]=20#243=20-=20fifthOnboardingView?= =?UTF-8?q?=20MVVM=20+=20Combine=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Factory/ViewControllerFactory.swift | 3 ++- .../FifthOnboardingViewController.swift | 23 +++++++++++++++---- .../ViewModel/FifthOnboardingViewModel.swift | 10 +++++++- .../FifthOnboardingViewModelImpl.swift | 22 +++++++++++++++++- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift index b6aec976..e5537800 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Coordinator/Factory/ViewControllerFactory.swift @@ -89,7 +89,8 @@ extension ViewControllerFactoryImpl { return viewController } func makeFifthOnboardingViewController(coordinator: AuthCoordinator) -> FifthOnboardingViewController { - let viewController = FifthOnboardingViewController(coordinator: coordinator) + let viewModel = FifthOnboardingViewModelImpl(coordinator: coordinator) + let viewController = FifthOnboardingViewController(viewModel: viewModel) return viewController } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift index 6ebe5913..bccf6571 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift @@ -7,6 +7,7 @@ import UIKit +import Combine import SnapKit import Then @@ -22,7 +23,11 @@ final class FifthOnboardingViewController: UIViewController { var fiveOnboardingModel: [FifthOnboardingModel] = FifthOnboardingModel.titles private var dataSource: UICollectionViewDiffableDataSource! = nil private lazy var safeArea = self.view.safeAreaLayoutGuide - private weak var coordinator: AuthCoordinator? + + private let viewModel: any FifthOnboardingViewModel + private var cancelBag = Set() + + private let loginButtonDidTapped = PassthroughSubject() // MARK: - UI Components @@ -32,8 +37,8 @@ final class FifthOnboardingViewController: UIViewController { private let gradientView = GradientView(color: .clear, color1: .ntdBlack!) // MARK: - init - init(coordinator: AuthCoordinator) { - self.coordinator = coordinator + init(viewModel: some FifthOnboardingViewModel) { + self.viewModel = viewModel super.init(nibName: nil, bundle: nil) } @@ -51,6 +56,7 @@ final class FifthOnboardingViewController: UIViewController { setLayout() setupDataSource() reloadData() + setBindings() } } @@ -71,6 +77,7 @@ extension FifthOnboardingViewController { $0.bounces = false $0.isScrollEnabled = false } + nextButton.do { var configuration = UIButton.Configuration.plain() configuration.image = .kakaoAppleIcon @@ -83,6 +90,7 @@ extension FifthOnboardingViewController { $0.configuration = configuration $0.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) } + arrowImage.do { $0.image = .splashBack } @@ -187,6 +195,13 @@ extension FifthOnboardingViewController { section.contentInsets = NSDirectionalEdgeInsets(top: 11, leading: 0, bottom: 0, trailing: 0) return section } + + private func setBindings() { + let input = FifthOnboardingViewModelInput( + loginButtonDidTapped: loginButtonDidTapped + ) + _ = viewModel.transform(input: input) + } } extension FifthOnboardingViewController { @@ -194,6 +209,6 @@ extension FifthOnboardingViewController { private func buttonTapped() { AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext5) - self.coordinator?.showSignUpViewController() + self.loginButtonDidTapped.send() } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift index b6c724d1..bbc67d59 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift @@ -5,4 +5,12 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +protocol FifthOnboardingViewModel: ViewModel where Input == FifthOnboardingViewModelInput, Output == FifthOnboardingViewModelOutput {} + +struct FifthOnboardingViewModelInput { + let loginButtonDidTapped: PassthroughSubject +} + +struct FifthOnboardingViewModelOutput {} diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift index 47b89506..e47fffe4 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift @@ -5,4 +5,24 @@ // Created by 강윤서 on 3/14/24. // -import Foundation +import Combine + +final class FifthOnboardingViewModelImpl: FifthOnboardingViewModel { + + private weak var coordinator: AuthCoordinator? + private var cancelBag = Set() + + init(coordinator: AuthCoordinator) { + self.coordinator = coordinator + } + + func transform(input: FifthOnboardingViewModelInput) -> FifthOnboardingViewModelOutput { + input.loginButtonDidTapped + .sink { [weak self] _ in + guard let self else { return } + self.coordinator?.showSignUpViewController() + } + .store(in: &cancelBag) + return FifthOnboardingViewModelOutput() + } +} From 7c9e126e091b778ce1d3bdc6335ea041517602c8 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Fri, 15 Mar 2024 01:44:37 +0900 Subject: [PATCH 10/16] =?UTF-8?q?[Chore]=20#243=20-=20=EC=A4=84=EB=B0=94?= =?UTF-8?q?=EA=BF=88=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewControllers/FourthOnboardingViewController.swift | 1 - .../ViewControllers/ThirdOnboardingViewController.swift | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift index 3de85e48..4aa93b5a 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift @@ -85,7 +85,6 @@ extension FourthOnboardingViewController { $0.configuration?.contentInsets = NSDirectionalEdgeInsets.init(top: 0, leading: 0, bottom: 0, trailing: 0) $0.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) } - } private func setLayout() { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift index 36096e8c..d4350f28 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift @@ -78,6 +78,7 @@ extension ThirdOnboardingViewController { $0.allowsMultipleSelection = true $0.delegate = self } + nextButton.do { $0.backgroundColor = isTapped ? .white : .gray2 $0.isUserInteractionEnabled = isTapped From 42fc6f3342f95ebc27c1ec6ad9731981dd1e0489 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Wed, 20 Mar 2024 14:07:20 +0900 Subject: [PATCH 11/16] =?UTF-8?q?[Chore]=20#243=20-=20=EA=B8=B0=EA=B8=B0?= =?UTF-8?q?=EB=8C=80=EC=9D=91=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iOS-NOTTODO.xcodeproj/project.pbxproj | 6 +++--- .../Global/Extensions/UIImageView+.swift | 2 +- .../Cell/OnboardingCollectionViewCell.swift | 2 +- .../Cell/SubOnboardingCollectionViewCell.swift | 12 ++++++------ .../FifthOnboardingViewController.swift | 12 ++++++------ .../FourthOnboardingViewController.swift | 8 ++++---- .../LogoOnboardingViewController.swift | 6 +++--- .../ViewControllers/OnboardingFooterView.swift | 4 ++-- .../ViewControllers/OnboardingHeaderView.swift | 18 +++++++++--------- .../SecondOnboardingViewController.swift | 2 +- .../ThirdOnboardingViewController.swift | 8 ++++---- 11 files changed, 40 insertions(+), 40 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj index 72046972..df5300d9 100644 --- a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj +++ b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj @@ -629,11 +629,11 @@ 09F6717E29CAD68100708725 /* Onboarding */ = { isa = PBXGroup; children = ( - 3B877D602BA195A80002DFCB /* ViewModel */, + 09F6719329CB6E7800708725 /* Cell */, 6C9628AA2A2220E2003ADE25 /* Lottie */, - 09F6719229CB6E6200708725 /* ViewControllers */, 09F6719129CB6E4D00708725 /* Model */, - 09F6719329CB6E7800708725 /* Cell */, + 09F6719229CB6E6200708725 /* ViewControllers */, + 3B877D602BA195A80002DFCB /* ViewModel */, ); path = Onboarding; sourceTree = ""; diff --git a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UIImageView+.swift b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UIImageView+.swift index f2191ad0..dd82d709 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UIImageView+.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UIImageView+.swift @@ -22,7 +22,7 @@ extension UIImageView { } else { guard let url = URL(string: urlString) else { return } let resource = KF.ImageResource(downloadURL: url, cacheKey: urlString) // URL로부터 이미지를 다운받고 String 타입의 URL을 캐시키로 지정하고 - self.kf.setImage(with: resource) // 이미지를 셋한다. + self?.kf.setImage(with: resource) // 이미지를 셋한다. } case .failure(let error): print(error) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Cell/OnboardingCollectionViewCell.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Cell/OnboardingCollectionViewCell.swift index c6f26905..97cb4aca 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Cell/OnboardingCollectionViewCell.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Cell/OnboardingCollectionViewCell.swift @@ -78,7 +78,7 @@ extension OnboardingCollectionViewCell { titleLabel.text = model.title titleLabel.snp.remakeConstraints { $0.centerY.equalToSuperview() - $0.leading.equalToSuperview().offset(20) + $0.leading.equalToSuperview().offset(20.adjusted) } } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Cell/SubOnboardingCollectionViewCell.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Cell/SubOnboardingCollectionViewCell.swift index 4a4446b6..29893d0e 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Cell/SubOnboardingCollectionViewCell.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/Cell/SubOnboardingCollectionViewCell.swift @@ -60,17 +60,17 @@ extension SubOnboardingCollectionViewCell { iconImage.snp.makeConstraints { $0.centerY.equalToSuperview() - $0.leading.equalToSuperview().offset(21) - $0.size.equalTo(36) + $0.leading.equalToSuperview().offset(21.adjusted) + $0.size.equalTo(36.adjusted) } tagLabel.snp.makeConstraints { - $0.leading.equalTo(iconImage.snp.trailing).offset(13) - $0.top.equalToSuperview().offset(15) + $0.leading.equalTo(iconImage.snp.trailing).offset(13.adjusted) + $0.top.equalToSuperview().offset(15.adjusted) } titleLabel.snp.makeConstraints { $0.leading.equalTo(tagLabel.snp.leading) - $0.top.equalTo(tagLabel.snp.bottom).offset(6) - $0.bottom.equalToSuperview().inset(15) + $0.top.equalTo(tagLabel.snp.bottom).offset(6.adjusted) + $0.bottom.equalToSuperview().inset(15.adjusted) } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift index bccf6571..5c693b16 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift @@ -101,22 +101,22 @@ extension FifthOnboardingViewController { nextButton.addSubview(arrowImage) nextButton.snp.makeConstraints { - $0.trailing.equalTo(safeArea).inset(34) - $0.size.equalTo(CGSize(width: 205, height: 24)) - $0.bottom.equalTo(safeArea).inset(12) + $0.trailing.equalTo(safeArea).inset(34.adjusted) + $0.size.equalTo(CGSize(width: 205.adjusted, height: 24.adjusted)) + $0.bottom.equalTo(safeArea).inset(12.adjusted) } arrowImage.snp.makeConstraints { - $0.size.equalTo(CGSize(width: 8, height: 16)) + $0.size.equalTo(CGSize(width: 8.adjusted, height: 16.adjusted)) $0.trailing.equalToSuperview() $0.centerY.equalToSuperview() } collectionView.snp.makeConstraints { $0.top.equalTo(safeArea) - $0.directionalHorizontalEdges.equalTo(safeArea).inset(27) + $0.directionalHorizontalEdges.equalTo(safeArea).inset(27.adjusted) $0.bottom.equalTo(nextButton.snp.top) } gradientView.snp.makeConstraints { - $0.bottom.equalTo(nextButton.snp.top).offset(-90) + $0.bottom.equalTo(nextButton.snp.top).offset(-90.adjusted) $0.top.equalTo(safeArea).offset(Numbers.height*0.5) $0.directionalHorizontalEdges.equalTo(safeArea) } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift index 4aa93b5a..26326f40 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift @@ -91,13 +91,13 @@ extension FourthOnboardingViewController { view.addSubviews(collectionView, gradientView, nextButton) nextButton.snp.makeConstraints { - $0.trailing.equalTo(safeArea).inset(34) - $0.size.equalTo(CGSize(width: 95, height: 24)) - $0.bottom.equalTo(safeArea).inset(12) + $0.trailing.equalTo(safeArea).inset(34.adjusted) + $0.size.equalTo(CGSize(width: 95.adjusted, height: 24.adjusted)) + $0.bottom.equalTo(safeArea).inset(12.adjusted) } collectionView.snp.makeConstraints { $0.top.equalTo(safeArea) - $0.directionalHorizontalEdges.equalTo(safeArea).inset(27) + $0.directionalHorizontalEdges.equalTo(safeArea).inset(27.adjusted) $0.bottom.equalTo(nextButton.snp.top) } gradientView.snp.makeConstraints { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift index 1931ff2f..e6daa94a 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift @@ -109,9 +109,9 @@ extension LogoOnboardingViewController { } nextButton.snp.makeConstraints { - $0.bottom.equalTo(safeArea).inset(10) - $0.directionalHorizontalEdges.equalTo(safeArea).inset(15) - $0.height.equalTo(50) + $0.bottom.equalTo(safeArea).inset(10.adjusted) + $0.directionalHorizontalEdges.equalTo(safeArea).inset(15.adjusted) + $0.height.equalTo(50.adjusted) } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/OnboardingFooterView.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/OnboardingFooterView.swift index 04cb39e5..c4b17ae6 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/OnboardingFooterView.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/OnboardingFooterView.swift @@ -51,9 +51,9 @@ extension OnboardingFooterView { addSubviews(iconImage, actionLabel) iconImage.snp.makeConstraints { - $0.top.equalToSuperview().offset(21) + $0.top.equalToSuperview().offset(21.adjusted) $0.centerX.equalToSuperview() - $0.height.equalTo(17) + $0.height.equalTo(17.adjusted) } actionLabel.snp.makeConstraints { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/OnboardingHeaderView.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/OnboardingHeaderView.swift index ea0061e8..e3b68c85 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/OnboardingHeaderView.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/OnboardingHeaderView.swift @@ -86,31 +86,31 @@ extension OnboardingHeaderView { addSubviews(pageControl, pageControlLabel, verticalStackView) pageControl.snp.makeConstraints { - $0.top.equalToSuperview().offset(21) - $0.size.equalTo(CGSize(width: 27, height: 6)) + $0.top.equalToSuperview().offset(21.adjusted) + $0.size.equalTo(CGSize(width: 27.adjusted, height: 6.adjusted)) $0.centerX.equalToSuperview() } pageControlLabel.snp.makeConstraints { - $0.top.equalTo(pageControl.snp.bottom).offset(10) + $0.top.equalTo(pageControl.snp.bottom).offset(10.adjusted) $0.centerX.equalToSuperview() - $0.height.equalTo(18) + $0.height.equalTo(18.adjusted) } verticalStackView.snp.makeConstraints { - $0.top.equalTo(pageControlLabel.snp.bottom).offset(43) + $0.top.equalTo(pageControlLabel.snp.bottom).offset(43.adjusted) $0.directionalHorizontalEdges.equalToSuperview() $0.bottom.equalToSuperview() } if isControl { titleLabel.snp.makeConstraints { - $0.bottom.equalToSuperview().inset(40) + $0.bottom.equalToSuperview().inset(40.adjusted) } horizontalStackView.snp.makeConstraints { - $0.bottom.equalTo(titleLabel.snp.top).inset(20) + $0.bottom.equalTo(titleLabel.snp.top).inset(20.adjusted) } flagImage.snp.makeConstraints { - $0.size.equalTo(20) + $0.size.equalTo(20.adjusted) } } else { horizontalStackView.snp.remakeConstraints { @@ -119,7 +119,7 @@ extension OnboardingHeaderView { } titleLabel.snp.remakeConstraints { $0.top.equalToSuperview() - $0.height.equalTo(50) + $0.height.equalTo(50.adjusted) } } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift index e557e8c5..4038fb63 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift @@ -79,7 +79,7 @@ extension SecondOnboardingViewController { collectionView.snp.makeConstraints { $0.top.equalTo(safeArea) - $0.directionalHorizontalEdges.equalTo(safeArea).inset(27) + $0.directionalHorizontalEdges.equalTo(safeArea).inset(27.adjusted) $0.bottom.equalTo(safeArea) } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift index d4350f28..0a04a6a0 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift @@ -103,13 +103,13 @@ extension ThirdOnboardingViewController { nextButton.snp.makeConstraints { $0.top.equalTo(collectionView.snp.bottom) - $0.bottom.equalTo(safeArea).inset(10) - $0.directionalHorizontalEdges.equalTo(safeArea).inset(15) - $0.height.equalTo(50) + $0.bottom.equalTo(safeArea).inset(10.adjusted) + $0.directionalHorizontalEdges.equalTo(safeArea).inset(15.adjusted) + $0.height.equalTo(50.adjusted) } collectionView.snp.makeConstraints { $0.top.equalTo(safeArea) - $0.directionalHorizontalEdges.equalTo(safeArea).inset(27) + $0.directionalHorizontalEdges.equalTo(safeArea).inset(27.adjusted) $0.bottom.equalTo(nextButton.snp.top) } } From 92b2cc8ccc7b895cc46c929570435a6e90ab0e63 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Wed, 20 Mar 2024 15:48:03 +0900 Subject: [PATCH 12/16] =?UTF-8?q?[Refactor]=20#243=20-=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20configuration=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Auth/AuthButtonView.swift | 53 +++++++------------ .../Auth/AuthViewController.swift | 46 +++++++--------- .../Auth/ViewModel/AuthViewModel.swift | 8 +++ .../Auth/ViewModel/AuthViewModelImpl.swift | 8 +++ 4 files changed, 55 insertions(+), 60 deletions(-) create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/ViewModel/AuthViewModel.swift create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/ViewModel/AuthViewModelImpl.swift diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthButtonView.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthButtonView.swift index f639d8a2..c8ed1ce1 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthButtonView.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthButtonView.swift @@ -10,13 +10,11 @@ import UIKit import SnapKit import Then -final class AuthButtonView: UIView { +final class AuthButton: UIButton { - // MARK: - UI Components + // MARK: - UI Properties - private var buttonView = UIView() - private var buttonIcon = UIImageView() - private var buttonLabel = UILabel() + private let image = UIImageView() // MARK: - View Life Cycles @@ -34,43 +32,32 @@ final class AuthButtonView: UIView { // MARK: - Methods -extension AuthButtonView { +extension AuthButton { private func setUI(title: String?, icon: UIImage?, color: UIColor?) { - buttonView.do { - $0.backgroundColor = color - $0.layer.cornerRadius = 5 - } + image.image = icon - buttonIcon.image = icon + self.backgroundColor = color + self.layer.cornerRadius = 5 - buttonLabel.do { - $0.text = title - $0.textColor = .systemBlack - $0.font = .Pretendard(.medium, size: 16) - } + var configuration = UIButton.Configuration.plain() + + configuration.title = title + configuration.titleAlignment = .center + configuration.attributedTitle?.font = .Pretendard(.medium, size: 16) + configuration.baseBackgroundColor = color + configuration.baseForegroundColor = .systemBlack + configuration.contentInsets = NSDirectionalEdgeInsets.init(top: 0, leading: 0, bottom: 0, trailing: 0) + + self.configuration = configuration } private func setLayout() { - addSubviews(buttonView) - buttonView.addSubviews(buttonIcon, buttonLabel) - - self.snp.makeConstraints { - $0.height.equalTo(53) - } - - buttonView.snp.makeConstraints { - $0.leading.trailing.equalToSuperview().inset(17) - $0.height.equalToSuperview() - } + addSubviews(image) - buttonIcon.snp.makeConstraints { - $0.centerX.equalTo(buttonView.snp.leading).offset(27) + image.snp.makeConstraints { + $0.leading.equalToSuperview().inset(14) $0.centerY.equalToSuperview() } - - buttonLabel.snp.makeConstraints { - $0.centerX.centerY.equalToSuperview() - } } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthViewController.swift index 7cf0ef57..3e7c478a 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthViewController.swift @@ -29,10 +29,8 @@ final class AuthViewController: UIViewController { private var loginSubLabel = UILabel() private var kakaoLoginImageView = UIImageView() - private var kakaoLoginButtonView = AuthButtonView(frame: .zero, title: I18N.kakaoLogin, icon: .kakaoLogo, color: .kakaoYellow) - private var appleLoginButtonView = AuthButtonView(frame: .zero, title: I18N.appleLogin, icon: .appleLogo, color: .white) - private var kakaoLoginButton = UIButton() - private var appleLoginButton = UIButton() + private var kakaoLoginButton = AuthButton(frame: .zero, title: I18N.kakaoLogin, icon: .kakaoLogo, color: .kakaoYellow) + private var appleLoginButton = AuthButton(frame: .zero, title: I18N.appleLogin, icon: .appleLogo, color: .white) private var moreButton = UIButton() private var conditionButton = UIButton() @@ -117,47 +115,41 @@ extension AuthViewController { private func setLayout() { - view.addSubviews(loginMainLabel, loginSubLabel, kakaoLoginImageView, kakaoLoginButtonView, appleLoginButtonView, kakaoLoginButton, appleLoginButton, moreButton) + view.addSubviews(loginMainLabel, loginSubLabel, kakaoLoginImageView, kakaoLoginButton, appleLoginButton, moreButton) moreButton.addSubviews(conditionButton, personalInfoButton) loginMainLabel.snp.makeConstraints { - $0.top.equalToSuperview().offset(155) - $0.leading.equalToSuperview().offset(29) + $0.top.equalToSuperview().offset(155.adjusted) + $0.leading.equalToSuperview().offset(29.adjusted) } loginSubLabel.snp.makeConstraints { - $0.top.equalTo(loginMainLabel.snp.bottom).offset(17) + $0.top.equalTo(loginMainLabel.snp.bottom).offset(17.adjusted) $0.leading.equalTo(loginMainLabel.snp.leading) } moreButton.snp.makeConstraints { - $0.bottom.equalToSuperview().offset(-65) + $0.bottom.equalToSuperview().offset(-65.adjusted) $0.centerX.equalToSuperview() } - appleLoginButtonView.snp.makeConstraints { - $0.leading.trailing.equalToSuperview() - $0.bottom.equalTo(moreButton.snp.top).offset(-14) - } - - kakaoLoginButtonView.snp.makeConstraints { - $0.leading.trailing.equalToSuperview() - $0.bottom.equalTo(appleLoginButtonView.snp.top).offset(-11) - } - - kakaoLoginImageView.snp.makeConstraints { - $0.bottom.equalTo(kakaoLoginButtonView.snp.top).offset(-9) - $0.leading.equalToSuperview().offset(22) - $0.width.equalTo(189) - $0.height.equalTo(37) + appleLoginButton.snp.makeConstraints { + $0.leading.trailing.equalToSuperview().inset(17.adjusted) + $0.bottom.equalTo(moreButton.snp.top).offset(-14.adjusted) + $0.height.equalTo(53.adjusted) } kakaoLoginButton.snp.makeConstraints { - $0.top.bottom.leading.trailing.equalTo(kakaoLoginButtonView) + $0.leading.trailing.equalToSuperview().inset(17.adjusted) + $0.bottom.equalTo(appleLoginButton.snp.top).offset(-11.adjusted) + $0.height.equalTo(53.adjusted) } - appleLoginButton.snp.makeConstraints { - $0.top.bottom.leading.trailing.equalTo(appleLoginButtonView) + kakaoLoginImageView.snp.makeConstraints { + $0.bottom.equalTo(kakaoLoginButton.snp.top).offset(-9.adjusted) + $0.leading.equalToSuperview().offset(22.adjusted) + $0.width.equalTo(189.adjusted) + $0.height.equalTo(37.adjusted) } conditionButton.snp.makeConstraints { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/ViewModel/AuthViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/ViewModel/AuthViewModel.swift new file mode 100644 index 00000000..6a32d3dc --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/ViewModel/AuthViewModel.swift @@ -0,0 +1,8 @@ +// +// AuthViewModel.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/20/24. +// + +import Foundation diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/ViewModel/AuthViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/ViewModel/AuthViewModelImpl.swift new file mode 100644 index 00000000..fff7b85f --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/ViewModel/AuthViewModelImpl.swift @@ -0,0 +1,8 @@ +// +// AuthViewModelImpl.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/20/24. +// + +import Foundation From 88d71c7faf4f19a703d1dfdbe6945c0541ec7052 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Wed, 20 Mar 2024 16:19:43 +0900 Subject: [PATCH 13/16] =?UTF-8?q?[Refactor]=20#243=20-=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20attribute=20=EC=84=A4=EC=A0=95=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=ED=95=A8=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Global/Extensions/UIButton+.swift | 13 ++++++ .../Auth/AuthViewController.swift | 42 ++----------------- 2 files changed, 16 insertions(+), 39 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UIButton+.swift b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UIButton+.swift index 6102cdc5..def1e7cb 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UIButton+.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UIButton+.swift @@ -17,4 +17,17 @@ extension UIButton { ) setAttributedTitle(attributedString, for: .normal) } + + func setUnderlines(target: [String]) { + guard let title = titleLabel?.text else { return } + let attributedString = NSMutableAttributedString(string: title) + target.forEach { + let range = (title as NSString).range(of: $0) + attributedString.addAttribute( + .underlineStyle, + value: NSUnderlineStyle.single.rawValue, + range: range) + } + setAttributedTitle(attributedString, for: .normal) + } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthViewController.swift index 3e7c478a..aae46f00 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Auth/AuthViewController.swift @@ -33,8 +33,6 @@ final class AuthViewController: UIViewController { private var appleLoginButton = AuthButton(frame: .zero, title: I18N.appleLogin, icon: .appleLogo, color: .white) private var moreButton = UIButton() - private var conditionButton = UIButton() - private var personalInfoButton = UIButton() // MARK: - init init(coordinator: AuthCoordinator) { @@ -64,12 +62,7 @@ extension AuthViewController { $0.textColor = .white $0.text = I18N.loginMain $0.numberOfLines = 2 - - let paragraphStyle = NSMutableParagraphStyle() - paragraphStyle.lineSpacing = $0.font.lineHeight * 0.2 - - let attributedText = NSAttributedString(string: $0.text ?? "", attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]) - $0.attributedText = attributedText + $0.setLineSpacing(lineSpacing: $0.font.lineHeight * 0.2) } loginSubLabel.do { @@ -77,12 +70,7 @@ extension AuthViewController { $0.textColor = .gray4 $0.text = I18N.loginSub $0.numberOfLines = 3 - - let paragraphStyle = NSMutableParagraphStyle() - paragraphStyle.lineSpacing = $0.font.lineHeight * 0.2 - - let attributedText = NSAttributedString(string: $0.text ?? "", attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]) - $0.attributedText = attributedText + $0.setLineSpacing(lineSpacing: $0.font.lineHeight * 0.2) } kakaoLoginImageView.image = .kakaoLoginLabel @@ -94,21 +82,7 @@ extension AuthViewController { $0.setTitle(I18N.moreAuth, for: .normal) $0.setTitleColor(.gray4, for: .normal) $0.titleLabel?.font = .Pretendard(.regular, size: 12) - } - - conditionButton.do { - $0.setTitle(I18N.condition, for: .normal) - $0.setTitleColor(.gray4, for: .normal) - $0.titleLabel?.font = .Pretendard(.regular, size: 12) - $0.setUnderline() - $0.addTarget(self, action: #selector(moreButtonTapped), for: .touchUpInside) - } - - personalInfoButton.do { - $0.setTitle(I18N.personalInfo, for: .normal) - $0.setTitleColor(.gray4, for: .normal) - $0.titleLabel?.font = .Pretendard(.regular, size: 12) - $0.setUnderline() + $0.setUnderlines(target: [I18N.condition, I18N.personalInfo]) $0.addTarget(self, action: #selector(moreButtonTapped), for: .touchUpInside) } } @@ -116,7 +90,6 @@ extension AuthViewController { private func setLayout() { view.addSubviews(loginMainLabel, loginSubLabel, kakaoLoginImageView, kakaoLoginButton, appleLoginButton, moreButton) - moreButton.addSubviews(conditionButton, personalInfoButton) loginMainLabel.snp.makeConstraints { $0.top.equalToSuperview().offset(155.adjusted) @@ -151,15 +124,6 @@ extension AuthViewController { $0.width.equalTo(189.adjusted) $0.height.equalTo(37.adjusted) } - - conditionButton.snp.makeConstraints { - $0.centerY.leading.equalToSuperview() - } - - personalInfoButton.snp.makeConstraints { - $0.centerY.trailing.equalToSuperview() - } - } // MARK: - @objc Methods From c0149a638b29d14d1d028d32eec5875e3436bc36 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Wed, 20 Mar 2024 17:18:53 +0900 Subject: [PATCH 14/16] =?UTF-8?q?[Add]=20#243=20-=20UIEvent=20=EA=B0=90?= =?UTF-8?q?=EC=A7=80=20publisher=20extension=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Global/Extensions/Combine+.swift | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Combine+.swift diff --git a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Combine+.swift b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Combine+.swift new file mode 100644 index 00000000..cd2b654f --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Combine+.swift @@ -0,0 +1,78 @@ +// +// Combine+.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 3/20/24. +// + +import Combine +import UIKit + +extension UIControl { + func controlPublisher(for event: UIControl.Event) -> UIControl.EventPublisher { + return UIControl.EventPublisher(control: self, event: event) + } + + // Publisher + struct EventPublisher: Publisher { + typealias Output = UIControl + typealias Failure = Never + + let control: UIControl + let event: UIControl.Event + + func receive(subscriber: S) + where S: Subscriber, Never == S.Failure, UIControl == S.Input { + let subscription = EventSubscription( + control: control, + subscriber: subscriber, + event: event + ) + subscriber.receive(subscription: subscription) + } + } + + // Subscription + fileprivate class EventSubscription: Subscription + where EventSubscriber.Input == UIControl, EventSubscriber.Failure == Never { + + let control: UIControl + let event: UIControl.Event + var subscriber: EventSubscriber? + + init(control: UIControl, subscriber: EventSubscriber, event: UIControl.Event) { + self.control = control + self.subscriber = subscriber + self.event = event + control.addTarget(self, action: #selector(eventDidOccur), for: event) + } + + func request(_ demand: Subscribers.Demand) {} + + func cancel() { + subscriber = nil + control.removeTarget(self, action: #selector(eventDidOccur), for: event) + } + + @objc func eventDidOccur() { + _ = subscriber?.receive(control) + } + } +} + +extension UITextField { + var textPublisher: AnyPublisher { + controlPublisher(for: .editingChanged) + .map { $0 as! UITextField } + .map { $0.text! } + .eraseToAnyPublisher() + } +} + +extension UIButton { + var tapPublisher: AnyPublisher { + controlPublisher(for: .touchUpInside) + .map { _ in } + .eraseToAnyPublisher() + } +} From 1fcfc2d40cc53b32ab5221378e856e5e7e8fcecd Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Wed, 20 Mar 2024 17:19:30 +0900 Subject: [PATCH 15/16] =?UTF-8?q?[Refactor]=20#243=20-=20=EC=95=B0?= =?UTF-8?q?=ED=94=8C=EB=A6=AC=ED=8A=9C=ED=8A=B8=20viewModel=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20&=20buttonTapped=20publisher=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FifthOnboardingViewController.swift | 19 ++++++++-------- .../FourthOnboardingViewController.swift | 18 +++++++-------- .../LogoOnboardingViewController.swift | 14 ++++++------ .../SecondOnboardingViewController.swift | 7 +++--- .../ThirdOnboardingViewController.swift | 22 +++++++++---------- .../ViewModel/FifthOnboardingViewModel.swift | 1 + .../FifthOnboardingViewModelImpl.swift | 9 ++++++++ .../ViewModel/FourthOnboardingViewModel.swift | 1 + .../FourthOnboardingViewModelImpl.swift | 9 ++++++++ .../LogoOnboardingViewModelImpl.swift | 1 + .../ViewModel/SecondOnboardingViewModel.swift | 1 + .../SecondOnboardingViewModelImpl.swift | 11 +++++++++- .../ViewModel/ThirdOnboardingViewModel.swift | 3 ++- .../ThirdOnboardingViewModelImpl.swift | 10 ++++++++- 14 files changed, 83 insertions(+), 43 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift index 5c693b16..79c9b0dc 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FifthOnboardingViewController.swift @@ -27,6 +27,7 @@ final class FifthOnboardingViewController: UIViewController { private let viewModel: any FifthOnboardingViewModel private var cancelBag = Set() + private let viewDidLoadSubject = PassthroughSubject() private let loginButtonDidTapped = PassthroughSubject() // MARK: - UI Components @@ -50,7 +51,7 @@ final class FifthOnboardingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding5) + viewDidLoadSubject.send() setUI() register() setLayout() @@ -88,7 +89,6 @@ extension FifthOnboardingViewController { configuration.baseForegroundColor = .white configuration.contentInsets = NSDirectionalEdgeInsets.init(top: 0, leading: 0, bottom: 0, trailing: 10) $0.configuration = configuration - $0.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) } arrowImage.do { @@ -198,17 +198,16 @@ extension FifthOnboardingViewController { private func setBindings() { let input = FifthOnboardingViewModelInput( + viewDidLoadSubject: viewDidLoadSubject, loginButtonDidTapped: loginButtonDidTapped ) _ = viewModel.transform(input: input) - } -} - -extension FifthOnboardingViewController { - @objc - private func buttonTapped() { - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext5) - self.loginButtonDidTapped.send() + nextButton.tapPublisher + .sink { [weak self] _ in + guard let self else { return } + self.loginButtonDidTapped.send() + } + .store(in: &cancelBag) } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift index 26326f40..ba62137e 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/FourthOnboardingViewController.swift @@ -25,6 +25,7 @@ final class FourthOnboardingViewController: UIViewController { private let viewModel: any FourthOnboardingViewModel private var cancelBag = Set() + private let viewDidLoadSubject = PassthroughSubject() private let buttonDidTapped = PassthroughSubject() // MARK: - UI Components @@ -48,7 +49,7 @@ final class FourthOnboardingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding4) + viewDidLoadSubject.send() setUI() register() setLayout() @@ -83,7 +84,6 @@ extension FourthOnboardingViewController { $0.configuration?.attributedTitle?.font = .Pretendard(.medium, size: 16) $0.configuration?.baseForegroundColor = .white $0.configuration?.contentInsets = NSDirectionalEdgeInsets.init(top: 0, leading: 0, bottom: 0, trailing: 0) - $0.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) } } @@ -147,16 +147,16 @@ extension FourthOnboardingViewController { private func setBindings() { let input = FourthOnboardingViewModelInput( + viewDidLoadSubject: viewDidLoadSubject, buttonDidTapped: buttonDidTapped ) _ = viewModel.transform(input: input) - } -} -extension FourthOnboardingViewController { - @objc - private func buttonTapped() { - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext4) - self.buttonDidTapped.send() + nextButton.tapPublisher + .sink { [weak self] _ in + guard let self else { return } + self.buttonDidTapped.send() + } + .store(in: &cancelBag) } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift index e6daa94a..abe485e9 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/LogoOnboardingViewController.swift @@ -97,7 +97,6 @@ extension LogoOnboardingViewController { $0.titleLabel?.font = .Pretendard(.semiBold, size: 16) $0.setTitleColor(.black, for: .normal) $0.setTitle(I18N.firstButton, for: .normal) - $0.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) } } @@ -120,16 +119,17 @@ extension LogoOnboardingViewController { startButtonTappedSubject: startButtonDidTapped ) _ = viewModel.transform(input: input) + + nextButton.tapPublisher + .sink { [weak self] in + guard let self else { return } + self.startButtonDidTapped.send() + } + .store(in: &cancelBag) } @objc private func videoDidFinishPlaying(notification: NSNotification) { nextButton.isHidden = false } - - @objc - private func buttonTapped() { - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingStart) - startButtonDidTapped.send() - } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift index 4038fb63..3c47d0d0 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/SecondOnboardingViewController.swift @@ -25,6 +25,7 @@ final class SecondOnboardingViewController: UIViewController { private let viewModel: any SecondOnboardingViewModel private var cancelBag = Set() + private let viewDidLoadSubject = PassthroughSubject() private let onbaordingCellTapped = PassthroughSubject() // MARK: - UI Components @@ -46,7 +47,7 @@ final class SecondOnboardingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding2) + viewDidLoadSubject.send() setUI() register() setLayout() @@ -63,6 +64,7 @@ extension SecondOnboardingViewController { collectionView.register(OnboardingCollectionViewCell.self, forCellWithReuseIdentifier: OnboardingCollectionViewCell.identifier) collectionView.register(OnboardingHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: OnboardingHeaderView.identifier) } + private func setUI() { view.backgroundColor = .ntdBlack @@ -122,6 +124,7 @@ extension SecondOnboardingViewController { private func setBindings() { let input = SecondOnboardingViewModelInput( + viewDidLoadSubject: viewDidLoadSubject, cellTapped: onbaordingCellTapped) _ = viewModel.transform(input: input) } @@ -129,8 +132,6 @@ extension SecondOnboardingViewController { extension SecondOnboardingViewController: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext2(select: SecondOnboardingModel.titles[indexPath.row].title)) - self.onbaordingCellTapped.send(indexPath) } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift index 0a04a6a0..acdcc7d6 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewControllers/ThirdOnboardingViewController.swift @@ -27,7 +27,8 @@ final class ThirdOnboardingViewController: UIViewController { private let viewModel: any ThirdOnboardingViewModel private var cancelBag = Set() - private let nextButtonDidTapped = PassthroughSubject() + private let viewDidLoadSubject = PassthroughSubject() + private let nextButtonDidTapped = PassthroughSubject<[String], Never>() // MARK: - UI Components @@ -50,7 +51,7 @@ final class ThirdOnboardingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding3) + viewDidLoadSubject.send() setUI() register() setLayout() @@ -86,7 +87,6 @@ extension ThirdOnboardingViewController { $0.titleLabel?.font = .Pretendard(.semiBold, size: 16) $0.setTitleColor(isTapped ? .black :.gray4, for: .normal) $0.setTitle(I18N.thirdButton, for: .normal) - $0.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) } } @@ -153,16 +153,16 @@ extension ThirdOnboardingViewController { private func setBindings() { let input = ThirdOnboardingViewModelInput( + viewDidLoadSubject: viewDidLoadSubject, nextButtonDidTapped: nextButtonDidTapped) _ = viewModel.transform(input: input) - } -} - -extension ThirdOnboardingViewController { - @objc - private func buttonTapped() { - AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext3(select: self.selectList)) - self.nextButtonDidTapped.send() + + nextButton.tapPublisher + .sink { [weak self] in + guard let self else { return } + self.nextButtonDidTapped.send(selectList) + } + .store(in: &cancelBag) } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift index bbc67d59..663f0309 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModel.swift @@ -10,6 +10,7 @@ import Combine protocol FifthOnboardingViewModel: ViewModel where Input == FifthOnboardingViewModelInput, Output == FifthOnboardingViewModelOutput {} struct FifthOnboardingViewModelInput { + let viewDidLoadSubject: PassthroughSubject let loginButtonDidTapped: PassthroughSubject } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift index e47fffe4..0bf163ce 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift @@ -20,9 +20,18 @@ final class FifthOnboardingViewModelImpl: FifthOnboardingViewModel { input.loginButtonDidTapped .sink { [weak self] _ in guard let self else { return } + AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext5) self.coordinator?.showSignUpViewController() } .store(in: &cancelBag) + + input.viewDidLoadSubject + .sink { [weak self] _ in + guard let self else { return } + AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding5) + } + .store(in: &cancelBag) + return FifthOnboardingViewModelOutput() } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift index 4095aece..f0d76267 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModel.swift @@ -10,6 +10,7 @@ import Combine protocol FourthOnboardingViewModel: ViewModel where Input == FourthOnboardingViewModelInput, Output == FourthOnboardingViewModelOutput {} struct FourthOnboardingViewModelInput { + let viewDidLoadSubject: PassthroughSubject let buttonDidTapped: PassthroughSubject } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift index 4c56e66a..85b5a1f6 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift @@ -20,9 +20,18 @@ final class FourthOnboardingViewModelImpl: FourthOnboardingViewModel { input.buttonDidTapped .sink { [weak self] _ in guard let self else { return } + AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext4) self.coordinator?.showFifthOnboardingViewController() } .store(in: &cancelBag) + + input.viewDidLoadSubject + .sink { [weak self] _ in + guard let self else { return } + AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding4) + } + .store(in: &cancelBag) + return FourthOnboardingViewModelOutput() } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift index 65c918eb..e7a7c6f7 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/LogoOnboardingViewModelImpl.swift @@ -20,6 +20,7 @@ final class LogoOnboardingViewModelImpl: LogoOnboardingViewModel { input.startButtonTappedSubject .sink { [weak self] _ in guard let self else { return } + AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingStart) self.coodinator?.showSecondOnboardingViewController() } .store(in: &cancelBag) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift index d057fa41..b29496a4 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModel.swift @@ -11,6 +11,7 @@ import Foundation protocol SecondOnboardingViewModel: ViewModel where Input == SecondOnboardingViewModelInput, Output == SecondOnboardingViewModelOutput { } struct SecondOnboardingViewModelInput { + let viewDidLoadSubject: PassthroughSubject let cellTapped: PassthroughSubject } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift index 4921d4dd..2e409b09 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift @@ -18,11 +18,20 @@ final class SecondOnboardingViewModelImpl: SecondOnboardingViewModel { func transform(input: SecondOnboardingViewModelInput) -> SecondOnboardingViewModelOutput { input.cellTapped - .sink { [weak self] _ in + .sink { [weak self] indexPath in guard let self else { return } + AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext2(select: SecondOnboardingModel.titles[indexPath.row].title)) self.coordinator?.showThirdOnboardingViewController() } .store(in: &cancelBag) + + input.viewDidLoadSubject + .sink { [weak self] _ in + guard let self else { return } + AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding2) + } + .store(in: &cancelBag) + return SecondOnboardingViewModelOutput() } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift index 4202b6af..4967bbf4 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModel.swift @@ -10,7 +10,8 @@ import Combine protocol ThirdOnboardingViewModel: ViewModel where Input == ThirdOnboardingViewModelInput, Output == ThirdOnboardingViewModelOutput {} struct ThirdOnboardingViewModelInput { - let nextButtonDidTapped: PassthroughSubject + let viewDidLoadSubject: PassthroughSubject + let nextButtonDidTapped: PassthroughSubject<[String], Never> } struct ThirdOnboardingViewModelOutput {} diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift index b469513e..af8f4a75 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift @@ -18,12 +18,20 @@ final class ThirdOnboardingViewModelImpl: ThirdOnboardingViewModel { func transform(input: ThirdOnboardingViewModelInput) -> ThirdOnboardingViewModelOutput { input.nextButtonDidTapped - .sink { [weak self] _ in + .sink { [weak self] selectList in guard let self else { return } + AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.OnboardingClick.clickOnboardingNext3(select: selectList)) self.coordinator?.showFourthOnboardingViewController() } .store(in: &cancelBag) + input.viewDidLoadSubject + .sink { [weak self] _ in + guard let self else { return } + AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding3) + } + .store(in: &cancelBag) + return ThirdOnboardingViewModelOutput() } } From d12321cbdf6eca54307dafc478ca7b870f1c69d7 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Wed, 20 Mar 2024 17:36:19 +0900 Subject: [PATCH 16/16] =?UTF-8?q?[Del]=20#243=20-=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift | 3 +-- .../Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift | 3 +-- .../Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift | 3 +-- .../Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift index 0bf163ce..c0415e5b 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FifthOnboardingViewModelImpl.swift @@ -26,8 +26,7 @@ final class FifthOnboardingViewModelImpl: FifthOnboardingViewModel { .store(in: &cancelBag) input.viewDidLoadSubject - .sink { [weak self] _ in - guard let self else { return } + .sink { AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding5) } .store(in: &cancelBag) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift index 85b5a1f6..b018f668 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/FourthOnboardingViewModelImpl.swift @@ -26,8 +26,7 @@ final class FourthOnboardingViewModelImpl: FourthOnboardingViewModel { .store(in: &cancelBag) input.viewDidLoadSubject - .sink { [weak self] _ in - guard let self else { return } + .sink { AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding4) } .store(in: &cancelBag) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift index 2e409b09..4dc576e1 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/SecondOnboardingViewModelImpl.swift @@ -26,8 +26,7 @@ final class SecondOnboardingViewModelImpl: SecondOnboardingViewModel { .store(in: &cancelBag) input.viewDidLoadSubject - .sink { [weak self] _ in - guard let self else { return } + .sink { AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding2) } .store(in: &cancelBag) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift index af8f4a75..fba5eaea 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Onboarding/ViewModel/ThirdOnboardingViewModelImpl.swift @@ -26,8 +26,7 @@ final class ThirdOnboardingViewModelImpl: ThirdOnboardingViewModel { .store(in: &cancelBag) input.viewDidLoadSubject - .sink { [weak self] _ in - guard let self else { return } + .sink { AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Onboarding.viewOnboarding3) } .store(in: &cancelBag)