Skip to content

Commit

Permalink
[Feat] #244 - modal MVVM 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
jeongdung-eo committed Mar 21, 2024
1 parent f7db265 commit 6f1016e
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import UIKit
import SnapKit
import KakaoSDKUser
import SafariServices
import Combine

enum ViewType {
case quit
Expand All @@ -20,8 +21,12 @@ final class NottodoModalViewController: UIViewController {

// MARK: - Properties

private weak var coordinator: MypageCoordinator?

private let viewWillAppearSubject = PassthroughSubject<Void, Never>()
private let modalViewControllerDismiss = PassthroughSubject<Void, Never>()
private let safariDismiss = PassthroughSubject<ViewType, Never>()
private let safariPresent = PassthroughSubject<Void, Never>()
private var viewModel: any ModalViewModel

private var viewType: ViewType? = .quit {
didSet {
setUI()
Expand All @@ -38,8 +43,8 @@ final class NottodoModalViewController: UIViewController {

// MARK: - init

init(coordinator: MypageCoordinator) {
self.coordinator = coordinator
init(viewModel: some ModalViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}

Expand All @@ -49,12 +54,19 @@ final class NottodoModalViewController: UIViewController {

// MARK: - Life Cycle

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

viewWillAppearSubject.send(())
}

override func viewDidLoad() {
super.viewDidLoad()
AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.AccountInfo.appearWithdrawalModal)

setUI()
setLayout()
setDelegate()
setBindings()
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
Expand All @@ -63,7 +75,7 @@ final class NottodoModalViewController: UIViewController {
let location = touch.location(in: self.view)

if !modalView.frame.contains(location) {
coordinator?.dismiss()
modalViewControllerDismiss.send(())
}
}
}
Expand Down Expand Up @@ -96,14 +108,23 @@ extension NottodoModalViewController {
withdrawView.delegate = self
safariViewController.delegate = self
}

private func setBindings() {
let input = ModalViewModelInput(viewWillAppearSubject: viewWillAppearSubject,
modalDismiss: modalViewControllerDismiss,
safariDismiss: safariDismiss,
safariPresent: safariPresent)

_ = viewModel.transform(input: input)
}
}

extension NottodoModalViewController: ModalDelegate {
func modalAction() {
switch viewType {
case .quitSurvey:
self.present(safariViewController, animated: true) {
self.withdrawal()
self.safariPresent.send(())
}
case .quit:
viewType = .quitSurvey
Expand All @@ -114,34 +135,13 @@ extension NottodoModalViewController: ModalDelegate {
}

func modalDismiss() {
coordinator?.dismiss() // 탈퇴 alert 취소
}
}

extension NottodoModalViewController {
func withdrawal() {
if !KeychainUtil.getBool(DefaultKeys.isAppleLogin) {
kakaoWithdrawal()
}
AuthService.shared.withdrawalAuth { _ in
AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.AccountInfo.completeWithdrawal)
}
}

func kakaoWithdrawal() {
UserApi.shared.unlink {(error) in
if let error = error {
print(error)
} else {
print("unlink() success.")
}
}
modalViewControllerDismiss.send(())
}
}

extension NottodoModalViewController: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.delegate = nil
coordinator?.connectAuthCoordinator(type: .quitSurvey)
safariDismiss.send(.quitSurvey)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// ModalViewModel.swift
// iOS-NOTTODO
//
// Created by JEONGEUN KIM on 3/21/24.
//

import Foundation
import Combine

protocol ModalViewModelPresentable {}

protocol ModalViewModel: ViewModel where Input == ModalViewModelInput, Output == ModalViewModelOutput {}

struct ModalViewModelInput {
let viewWillAppearSubject: PassthroughSubject<Void, Never>
let modalDismiss: PassthroughSubject<Void, Never>
let safariDismiss: PassthroughSubject<ViewType, Never>
let safariPresent: PassthroughSubject<Void, Never>
}

struct ModalViewModelOutput {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// ModalViewModelImpl.swift
// iOS-NOTTODO
//
// Created by JEONGEUN KIM on 3/21/24.
//

import Foundation
import Combine

final class ModalViewModelImpl: ModalViewModel {

private weak var coordinator: MypageCoordinator?
private var manager: MyPageManger
private var cancelBag = Set<AnyCancellable>()

init(coordinator: MypageCoordinator, manager: MyPageManger) {
self.coordinator = coordinator
self.manager = manager
}

func transform(input: ModalViewModelInput) -> ModalViewModelOutput {

input.viewWillAppearSubject
.sink { _ in
AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.AccountInfo.appearWithdrawalModal)
}
.store(in: &cancelBag)

input.modalDismiss
.sink { [weak self] _ in
self?.coordinator?.dismiss()
}
.store(in: &cancelBag)

input.safariDismiss
.sink { [weak self] type in
self?.coordinator?.connectAuthCoordinator(type: type)
}
.store(in: &cancelBag)

input.safariPresent
.sink { [weak self] _ in
self?.withdrawal()
}
.store(in: &cancelBag)
return Output()
}

func withdrawal() {
manager.withdrawl()
.sink(receiveCompletion: { event in
print("completion: \(event)")
}, receiveValue: { _ in
AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.AccountInfo.completeWithdrawal)
})
.store(in: &cancelBag)
}
}

0 comments on commit 6f1016e

Please sign in to comment.