Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor] #244 - 마이페이지 MVVM + Combine #255

Open
wants to merge 25 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2af95bb
[Feat] #244 - mypage manager 구현
jeongdung-eo Mar 15, 2024
b81b1be
[Feat] #244 - mypage account MVVM 적용
jeongdung-eo Mar 15, 2024
f56cb7a
[Feat] #244 - Mypage MVVM 적용
jeongdung-eo Mar 15, 2024
4b75ee5
[Fix] #244 - 코드 리뷰 반영
jeongdung-eo Mar 20, 2024
1dcfda4
[Merge] #244 - develop into 'feat/#244'
jeongdung-eo Mar 20, 2024
3269752
[Fix] #244 - 앰플리튜드 로직 수정
jeongdung-eo Mar 20, 2024
ad50ab6
[Feat] #244 - custom navigation view 구현
jeongdung-eo Mar 21, 2024
24b0fbb
[Add] #244 - notificationCenter & UIApplication extension 추가
jeongdung-eo Mar 21, 2024
52bb12b
[Feat] #244 - myPageAccount MVVM 적용
jeongdung-eo Mar 21, 2024
f7db265
[Fix] #244 - amplitude viewmodel로 이동
jeongdung-eo Mar 21, 2024
6f1016e
[Feat] #244 - modal MVVM 적용
jeongdung-eo Mar 21, 2024
939c4b1
[Fix] #244 - layout 수정
jeongdung-eo Mar 21, 2024
fb48362
[Move] #244 - modal관련 폴더링 수정
jeongdung-eo Mar 21, 2024
4f4f7aa
[Fix] #244 - Mypage Manaer 로직 변경
jeongdung-eo Mar 21, 2024
a48c85b
[Fix] #244 - mypage account 메모리 릭 해결 및 로직 수정
jeongdung-eo Mar 23, 2024
438c7c3
[Fix] #244 - mypage 로직 수정
jeongdung-eo Mar 23, 2024
3ae38d0
[Fix] #244 - navigation view button 로직 수정
jeongdung-eo Mar 23, 2024
46e1793
[Fix] #244 - 코드 라인 정리
jeongdung-eo Mar 23, 2024
d125830
[Del] #244 - 불필요한 파일 삭제
jeongdung-eo Mar 23, 2024
b11005e
[Fix] #244 - 네이밍 변경
jeongdung-eo Mar 23, 2024
8b6669e
[Merge] 'develop' into feat/#244
jeongdung-eo Mar 23, 2024
2d7e863
[Merge] #244 - conflict 해결 및 머지
jeongdung-eo Mar 23, 2024
86ac90f
[Fix] #244 - MyPage Factory 로직 수정
jeongdung-eo Mar 23, 2024
213d443
[Fix] #244 - lint 오류 수정
jeongdung-eo Mar 23, 2024
815fccd
[Fix] #244 - nested closure 로직 수정
jeongdung-eo Mar 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 172 additions & 82 deletions iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ final class MypageCoordinatorImpl: MypageCoordinator {
}

func showMyInfoViewController() {
let viewController = viewControllerFactory.makeMyInfoViewController(coordinator: self)
let viewController = viewControllerFactory.makeMyPageViewController(coordinator: self)
navigationController.setViewControllers([viewController], animated: true)
}

func showMyInfoAccountViewController() {
let viewController = viewControllerFactory.makeMyInfoAccountViewController(coordinator: self)
let viewController = viewControllerFactory.makeMyPageAccountViewController(coordinator: self)
viewController.hidesBottomBarWhenPushed = true
navigationController.pushViewController(viewController, animated: true)
}
Expand All @@ -59,10 +59,11 @@ final class MypageCoordinatorImpl: MypageCoordinator {
logoutAlert.addAction(logoutAction)
navigationController.present(logoutAlert, animated: true)
}

func connectAuthCoordinator(type: ViewType) {
navigationController.dismiss(animated: true) { [weak self] in
self?.finish()
guard let self else { return }
self.finish()
switch type {
case .quitSurvey:
KeychainUtil.removeUserInfo()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,45 @@
import Foundation

extension ViewControllerFactoryImpl {
func makeMyInfoViewController(coordinator: MypageCoordinator) -> MyInfoViewController {
let viewController = MyInfoViewController(coordinator: coordinator)

func makeMyPageManager() -> MyPageManger {
let authAPI = DefaultAuthService()
let manager = MyPageManagerImpl(authAPI: authAPI)
return manager
}

func makeMyPageViewModel(coordinator: MypageCoordinator) -> any MyPageViewModel {
let viewModel = MyPageViewModelImpl(coordinator: coordinator)
return viewModel
}

func makeMyPageViewController(coordinator: MypageCoordinator) -> MyPageViewController {
let viewModel = self.makeMyPageViewModel(coordinator: coordinator)
let viewController = MyPageViewController(viewModel: viewModel)
return viewController
}

func makeMyInfoAccountViewController(coordinator: MypageCoordinator) -> MyInfoAccountViewController {
let viewController = MyInfoAccountViewController(coordinator: coordinator)
func makeMyPageAccountViewModel(coordinator: MypageCoordinator) -> any MyPageAccountViewModel {
let manager = self.makeMyPageManager()
let viewModel = MyPageAccountViewModelImpl(coordinator: coordinator, manager: manager)
return viewModel
}

func makeMyPageAccountViewController(coordinator: MypageCoordinator) -> MyPageAccountViewController {
let viewModel = self.makeMyPageAccountViewModel(coordinator: coordinator)
let viewController = MyPageAccountViewController(viewModel: viewModel)
return viewController
}

func makeWithdrawViewModel(coordinator: MypageCoordinator) -> any ModalViewModel {
let manager = self.makeMyPageManager()
let viewModel = ModalViewModelImpl(coordinator: coordinator, manager: manager)
return viewModel
}

func makeWithdrawViewController(coordinator: MypageCoordinator) -> NottodoModalViewController {
let viewController = NottodoModalViewController(coordinator: coordinator)
let viewModel = self.makeWithdrawViewModel(coordinator: coordinator)
let viewController = NottodoModalViewController(viewModel: viewModel)
return viewController
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation

protocol MyPageFlowControllerFactory {
func makeMyInfoViewController(coordinator: MypageCoordinator) -> MyInfoViewController
func makeMyInfoAccountViewController(coordinator: MypageCoordinator) -> MyInfoAccountViewController
func makeMyPageViewController(coordinator: MypageCoordinator) -> MyPageViewController
func makeMyPageAccountViewController(coordinator: MypageCoordinator) -> MyPageAccountViewController
func makeWithdrawViewController(coordinator: MypageCoordinator) -> NottodoModalViewController
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

import UIKit

protocol ViewControllerFactory: UpdateFlowcontrollerFactory, AuthFlowControllerFactory, HomeFlowControllerFactory, MyPageFlowControllerFactory, AchieveFlowControllerFactory, TabBarControllerFactory, AuthFlowControllerFactory {}
protocol ViewControllerFactory: UpdateFlowcontrollerFactory, AuthFlowControllerFactory, HomeFlowControllerFactory, AchieveFlowControllerFactory, TabBarControllerFactory, AuthFlowControllerFactory, MyPageFlowControllerFactory {}

final class ViewControllerFactoryImpl: ViewControllerFactory {}
34 changes: 34 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/NotificationCenter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// NotificationCenter.swift
// iOS-NOTTODO
//
// Created by JEONGEUN KIM on 3/21/24.
//

import UIKit
import Combine

extension NotificationCenter {

enum Notification {
case willEnterForeground
case didEnterBackground
}

var willEnterForeground: AnyPublisher<NotificationCenter.Notification, Never> {
publisher(for: UIApplication.willEnterForegroundNotification)
.map { _ in return .willEnterForeground }
.eraseToAnyPublisher()
}

var didEnterBackground: AnyPublisher<NotificationCenter.Notification, Never> {
publisher(for: UIApplication.didEnterBackgroundNotification)
.map { _ in return .didEnterBackground }
.eraseToAnyPublisher()
}

var applicationState: AnyPublisher<NotificationCenter.Notification, Never> {
Publishers.Merge(willEnterForeground, didEnterBackground)
.eraseToAnyPublisher()
}
}
29 changes: 29 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UIApplication+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// UIApplication+.swift
// iOS-NOTTODO
//
// Created by JEONGEUN KIM on 3/21/24.
//

import UIKit

extension UIApplication {
private static let notificationSettingsURL: URL? = {
let settingsString: String
if #available(iOS 16, *) {
settingsString = UIApplication.openNotificationSettingsURLString
} else if #available(iOS 15.4, *) {
settingsString = UIApplicationOpenNotificationSettingsURLString
} else {
settingsString = UIApplication.openSettingsURLString
}
return URL(string: settingsString)
}()

func openAppNotificationSettings() {
guard
let url = UIApplication.notificationSettingsURL,
self.canOpenURL(url) else { return }
return open(url)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// MyPageManger.swift
// iOS-NOTTODO
//
// Created by JEONGEUN KIM on 3/15/24.
//

import Foundation
import Combine

protocol MyPageManger {
func logout() -> AnyPublisher<Void, Error>
func withdrawl() -> AnyPublisher<Void, Error>
func kakaoLogout()
func kakaoWithdrawal()
}
59 changes: 59 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Network/Manager/MyPageManagerImpl.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// MyPageManagerImpl.swift
// iOS-NOTTODO
//
// Created by JEONGEUN KIM on 3/15/24.
//

import Foundation
import Combine

import KakaoSDKUser

final class MyPageManagerImpl: MyPageManger {

private let authAPI: AuthServiceProtocol
private let cancelBag = Set<AnyCancellable>()

init(authAPI: AuthServiceProtocol) {
self.authAPI = authAPI
}

func logout() -> AnyPublisher<Void, Error> {
authAPI.logout()
.map { [weak self] _ in
self?.kakaoLogout()
}
.eraseToAnyPublisher()
}

func withdrawl() -> AnyPublisher<Void, Error> {
authAPI.withdrawal()
.map { [weak self] _ in
if !KeychainUtil.getBool(DefaultKeys.isAppleLogin) {
self?.kakaoWithdrawal()
}
}
.eraseToAnyPublisher()
}

func kakaoLogout() {
UserApi.shared.logout {(error) in
if let error = error {
print(error)
} else {
print("logout() success.")
}
}
}

func kakaoWithdrawal() {
UserApi.shared.unlink {(error) in
if let error = error {
print(error)
} else {
print("unlink() success.")
}
}
}
}
18 changes: 18 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Network/Service/Auth/AuthService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,27 @@
//

import Foundation
import Combine

import Moya

protocol AuthServiceProtocol {
func logout() -> AnyPublisher<Int, Error>
func withdrawal() -> AnyPublisher<Int, Error>
}

typealias DefaultAuthService = BaseService<AuthAPI>

extension DefaultAuthService: AuthServiceProtocol {
func logout() -> AnyPublisher<Int, Error> {
return requestWithCombineNoResult(AuthAPI.logout)
}

func withdrawal() -> AnyPublisher<Int, Error> {
return requestWithCombineNoResult(AuthAPI.withdrawal)
}
}

typealias AuthData = GeneralResponse<AuthResponseDTO>
typealias EmptyData = GeneralResponse<VoidType>

Expand Down
2 changes: 1 addition & 1 deletion iOS-NOTTODO/iOS-NOTTODO/Network/Service/BaseService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ extension BaseService {
}.eraseToAnyPublisher()
}

// status codea만 사용하는 경우
// status code만 사용하는 경우
func requestWithCombineNoResult(_ target: API) -> AnyPublisher<Int, Error> {
return Future { promise in
self.provider.request(target) { response in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,13 @@ final class AchievementViewController: UIViewController {
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - Life Cycle

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

viewWillAppearSubject.send(Date())
AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Achieve.viewAccomplish)
}

override func viewDidLoad() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ final class DetailAchievementViewController: UIViewController {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ final class AchievementViewModelImpl: AchievementViewModel {
}
.store(in: &cancelBag)

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

input.calendarCellTapped
.filter { [weak self] date -> Bool in
guard let percentage = self?.dataSource.value[date.formattedString()] else {
Expand Down
Loading