diff --git a/HMH_Tuist_iOS/Projects/Modules/Networks/Demo/Sources/ServiceTest/AuthServiceTest/AuthServiceView.swift b/HMH_Tuist_iOS/Projects/Modules/Networks/Demo/Sources/ServiceTest/AuthServiceTest/AuthServiceView.swift new file mode 100644 index 0000000..5e33fc2 --- /dev/null +++ b/HMH_Tuist_iOS/Projects/Modules/Networks/Demo/Sources/ServiceTest/AuthServiceTest/AuthServiceView.swift @@ -0,0 +1,161 @@ +// +// AuthServiceView.swift +// NetworksDemo +// +// Created by 류희재 on 11/23/24. +// Copyright © 2024 HMH-iOS. All rights reserved. +// + +import SwiftUI +import Networks +import Core +import Combine + +struct AuthServiceView: View { + + @StateObject var viewModel: AuthServiceViewModel + + var body: some View { + VStack { + HStack { + Button { + print("뒤로 가기") + } label: { + Image(systemName: "chevron.backward") + .resizable() + .foregroundColor(.white) + .frame(width: 12, height: 24) + } + .padding(.leading, 14) + + Spacer() + + Text("AuthServiceTest") + .foregroundStyle(Color( + red: 165 / 255.0, + green: 165 / 255.0, + blue: 187 / 255.0 + )) + .font(.title) + .bold() + .multilineTextAlignment(.center) + + Spacer() + } + .padding(.vertical, 18) + + ServiceListView(viewModel: viewModel) + .padding(.horizontal, 20) + .padding(.bottom, 25) + .frame(height: 360) + + Rectangle() + .foregroundColor(.white) + .frame(width: .infinity, height: 3) + .padding(.horizontal, 20) + .padding(.bottom, 25) + + Text(viewModel.state.networkLoggingText) + .padding(.top, 25) + .padding(.horizontal, 20) + .frame(width: 335, height: 240) + .background(.gray) + + Spacer() + } + .background(Color(asset: NetworksDemoAsset.blackground)) + } +} + +fileprivate struct ServiceListView: View { + private let viewModel: AuthServiceViewModel + + init(viewModel: AuthServiceViewModel) { + self.viewModel = viewModel + } + + let apiList: [String] = [ + "SignUp", + "SocialLogin" + ] + var body: some View { + VStack { + Spacer() + .frame(height: 24) + + ScrollView(.vertical, showsIndicators: true) { + ForEach(Array(apiList.enumerated()), id: \.element) { index, api in + ServiceCellView(apiTitle: api, index: index, viewModel: viewModel) + Rectangle() + .foregroundColor(.gray) + .frame(width: .infinity, height: 1) + } + } + } + } +} + +fileprivate struct ServiceCellView: View { + private let apiTitle: String + private let index: Int + @ObservedObject private var viewModel: AuthServiceViewModel + + init(apiTitle: String, index: Int, viewModel: AuthServiceViewModel) { + self.apiTitle = apiTitle + self.index = index + self.viewModel = viewModel + } + + + var body: some View { + HStack { + VStack(alignment: .leading) { + Text(apiTitle) + .foregroundStyle(Color( + red: 219 / 255.0, + green: 218 / 255.0, + blue: 231 / 255.0 + )) + .font(.title2) + .bold() + .frame(height: 2) + .padding(.bottom, 10) + + Text("테스트 결과: \(viewModel.state.resultText[index])") + .foregroundColor(.white) + .font(.body) + .bold() + } + .padding(.vertical, 18) + + Spacer() + + Button { + viewModel.send(action: .serviceButtonDidTap(index)) + } label: { + Text("Test") + .foregroundColor(.white) + .font(.title) + .bold() + .padding(.horizontal, 16) + .padding(.vertical, 8) + .background(Color( + red: 70 / 255.0, + green: 30 / 255.0, + blue: 229 / 255.0 + )) + .clipShape(RoundedRectangle(cornerRadius: 4)) + } + } + .frame(height: 80) + } +} + +#Preview { + return AuthServiceView( + viewModel: AuthServiceViewModel( + service: AuthService() + ) + ) +} + diff --git a/HMH_Tuist_iOS/Projects/Modules/Networks/Demo/Sources/ServiceTest/AuthServiceTest/AuthServiceViewModel.swift b/HMH_Tuist_iOS/Projects/Modules/Networks/Demo/Sources/ServiceTest/AuthServiceTest/AuthServiceViewModel.swift new file mode 100644 index 0000000..b794b3b --- /dev/null +++ b/HMH_Tuist_iOS/Projects/Modules/Networks/Demo/Sources/ServiceTest/AuthServiceTest/AuthServiceViewModel.swift @@ -0,0 +1,79 @@ +// +// AuthServiceViewModel.swift +// NetworksDemo +// +// Created by 류희재 on 11/23/24. +// Copyright © 2024 HMH-iOS. All rights reserved. +// + +import Foundation +import Combine +import Core +import Networks + +class AuthServiceViewModel: ObservableObject { + + //MARK: Action, State + + enum Action { + case serviceButtonDidTap(Int) + } + + struct State { + var resultText: [String] = Array(repeating: "", count: 2) + var networkLoggingText: String = "네트워크 결과창입니다!" + } + + //MARK: Dependency + + let service: AuthServiceType + + // MARK: - Init + init(service: AuthServiceType) { + self.service = service + self.state = State() + } + + //MARK: Properties + + @Published private(set) var state: State + private let cancelBag = CancelBag() + + //MARK: Methods + + func send(action: Action) { + switch action { + case .serviceButtonDidTap(let index): + switch index { + case 0: + service.signUp(request: .stub) + .sink(receiveCompletion: { [weak self] completion in + if case let .failure(error) = completion { + self?.state.networkLoggingText = error.description + self?.state.resultText[index] = "❌ 실패" + } + }) { [weak self] result in + self?.state.networkLoggingText = "\(result)" + self?.state.resultText[index] = "✅ 성공" + } + .store(in: cancelBag) + case 1: + service.socialLogin(request: .init(socialPlatform: "KAKAO")) + .sink(receiveCompletion: { [weak self] completion in + if case let .failure(error) = completion { + self?.state.networkLoggingText = error.description + self?.state.resultText[index] = "❌ 실패" + } + }) { [weak self] result in + self?.state.networkLoggingText = "\(result)" + self?.state.resultText[index] = "✅ 성공" + } + .store(in: cancelBag) + default: + break + } + } + } +} + +