diff --git a/Cherrish-iOS/Cherrish-iOS/Data/DataDependencyAssembler.swift b/Cherrish-iOS/Cherrish-iOS/Data/DataDependencyAssembler.swift index 6090a47e..4aa59b1f 100644 --- a/Cherrish-iOS/Cherrish-iOS/Data/DataDependencyAssembler.swift +++ b/Cherrish-iOS/Cherrish-iOS/Data/DataDependencyAssembler.swift @@ -42,6 +42,11 @@ final class DataDependencyAssembler: DependencyAssembler { return DefaultTreatmentRepository(networkService: self.networkService, userDefaultService: self.userDefaultService) } - + DIContainer.shared.register(type: MyPageInterface.self) { + return DefaultMyPageRepository( + networkService: self.networkService, + userDefaultService: self.userDefaultService + ) + } } } diff --git a/Cherrish-iOS/Cherrish-iOS/Data/Model/UserInfoResponseDTO.swift b/Cherrish-iOS/Cherrish-iOS/Data/Model/UserInfoResponseDTO.swift new file mode 100644 index 00000000..c630721f --- /dev/null +++ b/Cherrish-iOS/Cherrish-iOS/Data/Model/UserInfoResponseDTO.swift @@ -0,0 +1,19 @@ +// +// UserInfoResponseDTO.swift +// Cherrish-iOS +// +// Created by 이나연 on 1/20/26. +// + +import Foundation + +struct UserInfoResponseDTO: Decodable { + let name: String + let daysSinceSignup: Int +} + +extension UserInfoResponseDTO { + func toEntity() -> UserInfoEntity { + .init(name: name, daysSinceSignup: daysSinceSignup) + } +} diff --git a/Cherrish-iOS/Cherrish-iOS/Data/Network/EndPoint/MyPageAPI.swift b/Cherrish-iOS/Cherrish-iOS/Data/Network/EndPoint/MyPageAPI.swift new file mode 100644 index 00000000..98935bb9 --- /dev/null +++ b/Cherrish-iOS/Cherrish-iOS/Data/Network/EndPoint/MyPageAPI.swift @@ -0,0 +1,58 @@ +// +// MyPageAPI.swift +// Cherrish-iOS +// +// Created by 이나연 on 1/20/26. +// + +import Foundation + +import Alamofire + +enum MyPageAPI { + case users(userID: Int) +} + +extension MyPageAPI: EndPoint { + var basePath: String { + return "/api" + } + + var path: String { + switch self { + case .users: + return "/users" + } + } + + var method: Alamofire.HTTPMethod { + switch self { + case .users: + return .get + } + } + + var headers: HeaderType { + switch self { + case .users(let userID): + return .withAuth(userID: userID) + } + } + + var parameterEncoding: any Alamofire.ParameterEncoding { + switch self { + case .users: + return URLEncoding.default + } + } + + var queryParameters: [String : Any]? { + return nil + } + + var bodyParameters: Alamofire.Parameters? { + return nil + } + + +} diff --git a/Cherrish-iOS/Cherrish-iOS/Data/Repository/MyPageRepository.swift b/Cherrish-iOS/Cherrish-iOS/Data/Repository/MyPageRepository.swift new file mode 100644 index 00000000..32a25075 --- /dev/null +++ b/Cherrish-iOS/Cherrish-iOS/Data/Repository/MyPageRepository.swift @@ -0,0 +1,30 @@ +// +// MyPageRepository.swift +// Cherrish-iOS +// +// Created by 이나연 on 1/20/26. +// + +import Foundation + +struct DefaultMyPageRepository: MyPageInterface { + private let networkService: NetworkService + private let userDefaultService: UserDefaultService + + init( + networkService: NetworkService, + userDefaultService: UserDefaultService + ) { + self.networkService = networkService + self.userDefaultService = userDefaultService + } + + func fetchUserInfo() async throws -> UserInfoEntity { + let userID: Int = userDefaultService.load(key: .userID) ?? 1 + let response = try await networkService.request( + MyPageAPI.users(userID: userID), + decodingType: UserInfoResponseDTO.self) + + return response.toEntity() + } +} diff --git a/Cherrish-iOS/Cherrish-iOS/Domain/DomainDependencyAssembler.swift b/Cherrish-iOS/Cherrish-iOS/Domain/DomainDependencyAssembler.swift index 1b8726cd..f8160306 100644 --- a/Cherrish-iOS/Cherrish-iOS/Domain/DomainDependencyAssembler.swift +++ b/Cherrish-iOS/Cherrish-iOS/Domain/DomainDependencyAssembler.swift @@ -68,5 +68,13 @@ final class DomainDependencyAssembler: DependencyAssembler { DIContainer.shared.register(type: FetchTreatmentsUseCase.self) { return DefaultFetchTreatmentsUseCase(repository: treatmentRepository) } + + guard let myPageRepository = DIContainer.shared.resolve(type: MyPageInterface.self) else { + return + } + + DIContainer.shared.register(type: FetchUserInfoUseCase.self) { + return DefaultFetchUserInfoUserCase(repository: myPageRepository) + } } } diff --git a/Cherrish-iOS/Cherrish-iOS/Domain/Interface/MyPageInterface.swift b/Cherrish-iOS/Cherrish-iOS/Domain/Interface/MyPageInterface.swift new file mode 100644 index 00000000..18095358 --- /dev/null +++ b/Cherrish-iOS/Cherrish-iOS/Domain/Interface/MyPageInterface.swift @@ -0,0 +1,12 @@ +// +// MyPageInterface.swift +// Cherrish-iOS +// +// Created by 이나연 on 1/20/26. +// + +import Foundation + +protocol MyPageInterface { + func fetchUserInfo() async throws -> UserInfoEntity +} diff --git a/Cherrish-iOS/Cherrish-iOS/Domain/Model/UserInfoEntity.swift b/Cherrish-iOS/Cherrish-iOS/Domain/Model/UserInfoEntity.swift new file mode 100644 index 00000000..b7ce916b --- /dev/null +++ b/Cherrish-iOS/Cherrish-iOS/Domain/Model/UserInfoEntity.swift @@ -0,0 +1,13 @@ +// +// UserInfoEntity.swift +// Cherrish-iOS +// +// Created by 이나연 on 1/20/26. +// + +import Foundation + +struct UserInfoEntity { + let name: String + let daysSinceSignup: Int +} diff --git a/Cherrish-iOS/Cherrish-iOS/Domain/UseCase/FetchUserInfoUseCase.swift b/Cherrish-iOS/Cherrish-iOS/Domain/UseCase/FetchUserInfoUseCase.swift new file mode 100644 index 00000000..80991048 --- /dev/null +++ b/Cherrish-iOS/Cherrish-iOS/Domain/UseCase/FetchUserInfoUseCase.swift @@ -0,0 +1,24 @@ +// +// FetchUserInfoUseCase.swift +// Cherrish-iOS +// +// Created by 이나연 on 1/20/26. +// + +import Foundation + +protocol FetchUserInfoUseCase { + func execute() async throws -> UserInfoEntity +} + +struct DefaultFetchUserInfoUserCase: FetchUserInfoUseCase { + private let repository: MyPageInterface + + init(repository: MyPageInterface) { + self.repository = repository + } + + func execute() async throws -> UserInfoEntity { + return try await repository.fetchUserInfo() + } +} diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/MyPage/MyPageView.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/MyPage/MyPageView.swift index 9f3c60ea..812a4419 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/MyPage/MyPageView.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/MyPage/MyPageView.swift @@ -8,6 +8,8 @@ import SwiftUI struct MyPageView: View { + @StateObject var viewModel: MyPageViewModel + var body: some View { VStack { Spacer() @@ -18,6 +20,13 @@ struct MyPageView: View { .padding(.horizontal, 35) grayEmptyBar } + .task { + do { + try await viewModel.fetchUserInfo() + } catch { + CherrishLogger.error(error) + } + } } } @@ -29,10 +38,10 @@ extension MyPageView { .frame(width: 48.adjustedW, height: 48.adjustedH) VStack(alignment: .leading, spacing: 0){ - TypographyText("안녕하세요, 김채채 님", style: .title1_sb_18, color: .gray1000) + TypographyText("안녕하세요, \(viewModel.name)님", style: .title1_sb_18, color: .gray1000) .frame(height: 27.adjustedH) - TypographyText("관리 시작 D + 13", style: .body1_m_14, color: .gray800) + TypographyText("관리 시작 D + \(viewModel.day)", style: .body1_m_14, color: .gray800) .frame(height: 20.adjustedH) } diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/MyPage/MyPageViewModel.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/MyPage/MyPageViewModel.swift new file mode 100644 index 00000000..003b8a1a --- /dev/null +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/MyPage/MyPageViewModel.swift @@ -0,0 +1,26 @@ +// +// MyPageViewModel.swift +// Cherrish-iOS +// +// Created by 이나연 on 1/20/26. +// + +import Foundation + +final class MyPageViewModel: ObservableObject { + @Published private(set) var name: String = "" + @Published private(set) var day: Int = 1 + + private let fetchUserInfoUseCase: FetchUserInfoUseCase + + init(fetchUserInfoUseCase: FetchUserInfoUseCase) { + self.fetchUserInfoUseCase = fetchUserInfoUseCase + } + + @MainActor + func fetchUserInfo() async throws { + let response = try await fetchUserInfoUseCase.execute() + name = response.name + day = response.daysSinceSignup + } +} diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/SplashView.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/SplashView.swift index c2be14aa..24193cc7 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/SplashView.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/SplashView.swift @@ -10,13 +10,7 @@ import SwiftUI struct SplashView: View { @EnvironmentObject private var appCoordinator: AppCoordinator private let userDefaultService: UserDefaultService = DefaultUserDefaultService() - - private let userDefaultService: UserDefaultService - - init(userDefaultService: UserDefaultService = DefaultUserDefaultService()) { - self.userDefaultService = userDefaultService - } - + var body: some View { ZStack(alignment: .center) { LinearGradient( diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/PresentationDependencyAssembler.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/PresentationDependencyAssembler.swift index d491900a..6c5b75a3 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/PresentationDependencyAssembler.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/PresentationDependencyAssembler.swift @@ -71,5 +71,13 @@ final class PresentationDependencyAssembler: DependencyAssembler { DIContainer.shared.register(type: TreatmentViewModel.self) { return TreatmentViewModel(fetchTreatmentsUseCase: fetchTreatmentsUseCase) } + + guard let fetchUserInfoUseCase = DIContainer.shared.resolve(type: FetchUserInfoUseCase.self) else { + return + } + + DIContainer.shared.register(type: MyPageViewModel.self) { + return MyPageViewModel(fetchUserInfoUseCase: fetchUserInfoUseCase) + } } } diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/ViewFactory.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/ViewFactory.swift index 3bd8ec20..ca56d8a8 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/ViewFactory.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/ViewFactory.swift @@ -62,7 +62,10 @@ final class ViewFactory: ViewFactoryProtocol { } func makeMyPageView() -> MyPageView { - return MyPageView() + guard let viewModel = DIContainer.shared.resolve(type: MyPageViewModel.self) else { + fatalError() + } + return MyPageView(viewModel: viewModel) } func makeSelectTreatmentView() -> SelectTreatmentView {