Skip to content

Commit

Permalink
Merge pull request #90 from Team-HMH/refactor/#84
Browse files Browse the repository at this point in the history
Refactor [#84] 클린 아키텍쳐로 리팩토링
  • Loading branch information
HELLOHIDI authored Sep 23, 2024
2 parents cbfc1c7 + 0de03e3 commit 041a82d
Show file tree
Hide file tree
Showing 24 changed files with 1,058 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class UserManager: ObservableObject {
appState = AppState(rawValue: appStateString) ?? .login
}

func clearLogout() {
public func clearLogout() {
accessToken = ""
refreshToken = ""
socialToken = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@

import Foundation

struct EmptyResponseDTO: Codable { }
public struct EmptyResponseDTO: Codable { }
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

import Foundation

struct GetUserDataResponseDTO: Codable {
let name: String
let point: Int
public struct GetUserDataResponseDTO: Codable {
public let name: String
public let point: Int

enum CodingKeys: CodingKey {
case name
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// DIContainer.swift
// MyPageFeatureInterface
//
// Created by 류희재 on 8/13/24.
// Copyright © 2024 HMH-iOS. All rights reserved.
//

import Foundation

class DIContainer: ObservableObject {
var services: ServiceType

init(services: ServiceType) {
self.services = services
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// MyPageUseCase.swift
// MyPageFeature
//
// Created by 류희재 on 9/3/24.
// Copyright © 2024 HMH-iOS. All rights reserved.
//

import Foundation
import Combine
import Core
import Domain

protocol MyPageUseCaseType {
func getUserDate() -> AnyPublisher<GetUserDataResponseDTO, Error>
func logout()
func revokeUser()
}

final class MyPageUseCase: MyPageUseCaseType {
private var container: DIContainer
private var cancelBag = CancelBag()

init(container: DIContainer) {
self.container = container
}

func getUserDate() -> AnyPublisher<GetUserDataResponseDTO, Error> {
container.services.userService.getUserData()
.map { $0.data! }
.eraseToAnyPublisher()
}

func logout() {
container.services.authService.logoutUser()
.sink { _ in
} receiveValue: { _ in
UserManager.shared.clearLogout()
}.store(in: cancelBag)
}

func revokeUser() {
container.services.authService.revokeUser()
.sink { _ in
} receiveValue: { _ in
UserManager.shared.revokeData()
}.store(in: cancelBag)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// MyPageButtonType.swift
// MyPageFeatureInterface
//
// Created by 류희재 on 8/13/24.
// Copyright © 2024 HMH-iOS. All rights reserved.
//

import Foundation

import DSKit
import UIKit

enum MyPageButtonType_Refactor {
case travel
case market
case term
case info

var titleText: String {
switch self {
case .travel:
return StringLiteral.MyPageButton.travel
case .market:
return StringLiteral.MyPageButton.market
case .term:
return StringLiteral.MyPageButton.term
case .info:
return StringLiteral.MyPageButton.info
}
}

var imageName: String? {
switch self {
case .travel:
return "map"
case .market:
return "market"
case .term, .info:
return nil
}
}

var clickAction: Void {
switch self {
case .travel:
let url = URL(string: StringLiteral.MyPageURL.term)!
UIApplication.shared.open(url)
case .market:
let url = URL(string: StringLiteral.MyPageURL.info)!
UIApplication.shared.open(url)
default:
break
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// MyPageButton_Refactor.swift
// MyPageFeatureInterface
//
// Created by 류희재 on 8/13/24.
// Copyright © 2024 HMH-iOS. All rights reserved.
//


import SwiftUI

import DSKit

struct MyPageButton_Refactor: View {

var buttonType: MyPageButtonType_Refactor

var body: some View {
ZStack {
HStack() {
if let image = buttonType.imageName {
Image(image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 24, height: 24)
.padding(.trailing, 15)
}
Text(buttonType.titleText)
.font(.text5_medium_16)
Spacer()
Image(uiImage: buttonType == .travel ? DSKitAsset.chevrongray.image : DSKitAsset.chevronRight.image)
}
.frame(maxWidth: .infinity)
.frame(height: 58)
.foregroundColor(buttonType == .travel ? DSKitAsset.gray5.swiftUIColor : DSKitAsset.whiteText.swiftUIColor)
}
.background(DSKitAsset.blackground.swiftUIColor)
.onTapGesture {
buttonType.clickAction
}
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// MyPageViewModel.swift
// HMH_iOS
//
// Created by Seonwoo Kim on 4/12/24.
//

import Combine

import Core
import DSKit

class MyPageViewModel_Refactor: ObservableObject {

private var useCase: MyPageUseCaseType
private var cancelBag = CancelBag()

init(useCase: MyPageUseCaseType) {
self.useCase = useCase
}

@Published private(set) var state = State(
alertType: .logout,
name: "",
point: 0
)

//MARK: Action

enum Action {
case onAppearEvent
case logoutButtonDidTap
case withdrawButtonDidTap
case confirmButtonDidTap
}

//MARK: State

struct State {
var alertType: CustomAlertType
var name: String
var point: Int
}

func send(action: Action) {
switch action {
case .onAppearEvent:
useCase.getUserDate()
.sink { _ in
} receiveValue: { [weak self] data in
self?.state.name = data.name
self?.state.point = data.point
}.store(in: cancelBag)

case .logoutButtonDidTap:
state.alertType = .logout

case .withdrawButtonDidTap:
state.alertType = .withdraw

case .confirmButtonDidTap:
state.alertType == .logout ? useCase.logout() : useCase.revokeUser()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//
// MyPageView.swift
// HMH_iOS
//
// Created by Seonwoo Kim on 3/12/24.
//

import SwiftUI

import DSKit
import Core

public struct MyPageView_Refactor: View {
@State private var isPresented: Bool = false
@StateObject var viewModel: MyPageViewModel_Refactor

public var body: some View {
VStack {
Spacer()
.frame(height: 64)
ProfileView()
Spacer()
.frame(height: 36)
MyInfoView()
Spacer()
.frame(height: 34)
HMHInfoView()
Spacer()
AccountControlView()
}
.onAppear { viewModel.send(action: .onAppearEvent)}
.padding(20)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(DSKitAsset.blackground.swiftUIColor)
.customAlert(
isPresented: $isPresented,
customAlert: {
CustomAlertView(
alertType: viewModel.state.alertType,
confirmBtn: CustomAlertButtonView(
buttonType: .Confirm,
alertType: viewModel.state.alertType,
isPresented: $isPresented,
action: {
UserManager.shared.appStateString = "login"
viewModel.send(action: .confirmButtonDidTap)
}
),
cancelBtn: CustomAlertButtonView(
buttonType: .Cancel,
alertType: viewModel.state.alertType,
isPresented: $isPresented,
action: { isPresented = false }
), currentPoint: 0, usagePoint: 0
)
}
)
}
}

extension MyPageView_Refactor {
private func ProfileView() -> some View {
VStack {
Image(uiImage: DSKitAsset.profile.image)
.frame(width: 54, height: 54)
.padding(10)
Text(viewModel.state.name)
.font(.title4_semibold_20)
Spacer()
.frame(height: 16)
HStack {
Text(StringLiteral.MyPageAccountControl.point)
.font(.text6_medium_14)
Text("\(viewModel.state.point)")
.font(.text6_medium_14)
}
.frame(maxWidth: .infinity)
.frame(height: 40)
.background(DSKitAsset.gray7.swiftUIColor)
.cornerRadius(8)
}
.foregroundColor(DSKitAsset.whiteText.swiftUIColor)
.frame(width: 133, height: 150)
}

private func MyInfoView() -> some View {
VStack(spacing: 0) {
MyPageButton_Refactor(buttonType: .travel)
MyPageButton_Refactor(buttonType: .market)
}
.background(DSKitAsset.gray7.swiftUIColor)
}

private func HMHInfoView() -> some View {
VStack(alignment: .leading, spacing: 0) {
Text("정보")
.font(.text4_semibold_16)
.foregroundColor(DSKitAsset.gray2.swiftUIColor)
.padding(.vertical, 14)
MyPageButton_Refactor(buttonType: .info)
MyPageButton_Refactor(buttonType: .term)
}
}

private func AccountControlView() -> some View {
HStack {
Text(StringLiteral.MyPageAccountControl.logout)
.font(.text6_medium_14)
.onTapGesture {
isPresented = true
viewModel.send(action: .logoutButtonDidTap)
}
Rectangle()
.frame(width: 1, height: 16)
Text(StringLiteral.MyPageAccountControl.revoke)
.font(.text6_medium_14)
.onTapGesture {
isPresented = true
viewModel.send(action: .withdrawButtonDidTap)
}
}
.foregroundColor(DSKitAsset.gray3.swiftUIColor)
.frame(height: 77)
}
}

Loading

0 comments on commit 041a82d

Please sign in to comment.