-
Notifications
You must be signed in to change notification settings - Fork 0
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] #241 - 성취뷰 MVVM + Combine #242
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네트워크 통신 코드에도 컴바인 적용해주셔서 감사합니다!! 코드 보면서 헷갈리는 부분 질문 남겼어용,,💗
return ["Content-Type": "application/json", | ||
"Authorization": "\(KeychainUtil.getAccessToken())"] | ||
} | ||
// status codea만 사용하는 경우 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code로 바꿔주세욤><
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넹><
import Foundation | ||
import Combine | ||
|
||
protocol DetailAchievementViewModelPresentable {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 Presentable 프로토콜이 하는 역할이 무엇인지 잘 모르겠어서 사용하지 않았는데 참고 레포에서 혹시 다른 쓰임이 있었을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
카톡에서 이야기했던 것 처럼 ViewController Factory 내에서 VC가 구체적인 타입이 아닌 추상화된 인터페이스인 ViewModel & Presentable에 의존하게 됩니다! Presentable은 데이터 프로퍼티를 전달하기 위함임돵!
@@ -61,7 +73,7 @@ final class DetailAchievementViewController: UIViewController { | |||
|
|||
if !collectionView.frame.contains(location) { | |||
AmplitudeAnalyticsService.shared.send(event: AnalyticsEvent.Achieve.closeDailyMissionModal) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
View는 UI 관련 처리만 남겨야한다고 생각해서 Amplitude 관련 코드는 ViewModel이 처리하는게 좋지 않을까 판단했는데 정은님 생각은 어떠신가요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오호! 동의합니당! 이 로직도 뷰모델에서 처리하도록 하겠습니당 !
var config = config | ||
guard let itemCount = self.dataSource?.snapshot().itemIdentifiers(inSection: .main).count else { return config } | ||
guard let itemCount = self?.dataSource?.snapshot().itemIdentifiers(inSection: .main).count else { return config } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self도 guard로 한 번 확인해주는게 좋을 듯 합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넹 ><!
func getAchieveCalendar(month: String) -> AnyPublisher<CalendarEventData, Error> { | ||
return missionAPI.getAchieveCalendar(month: month) | ||
.map { response in | ||
self.convertResponseToCalendarEventData(response) | ||
} | ||
.compactMap { $0 } | ||
.eraseToAnyPublisher() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
실제 API 호출은 API에서 해주는 것이고 Manager에서는 디코딩한 값을 DTO에 맞게 변환해준다고 이해했는데 맞나요.. ?🥹
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
실제 API호출은 Service에서 이루어지고 Manager에서는 필요한 API를 호출하고, 결과를 DTO로 변환하여 반환해줍니당!
|
||
private lazy var safeArea = self.view.safeAreaLayoutGuide | ||
|
||
private let dataSource = CurrentValueSubject<[String: Float], Never>([:]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요 부분이 성취뷰에서 날짜를 클릭했을 때 부분인가요?-? CurrentValueSubject로 사용하신 이유가 궁금합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
calendar UI 속성을 변경하는 부분에서 dataSource의 value 값에 접근하기 위해서 CurrentValueSubject으로 선언했습니다!
protocol DetailAchievementViewModelPresentable { | ||
func selectedDate(_ date: String) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 공통적으로 적용되는 기본적인 기능을 구현한 베이스 클래스
- 네트워크 요청을 처리하고 응답을 받아오는 등의 작업을 수행
🫧 작업한 내용
[화면 간 API 호출 중복 문제 해결을 위한 Service Layer 재구성과 Manager도입]
#239
중복된 API 호출
초기에는 각 화면에서 필요한 API에 따라 별도의 API Service를 사용하여 개발.
그러나 이로 인해 같은 API가 여러 화면에서 중복 호출되는 문제가 발생.
역할(endpoint)에 따라 분리된 API Service
API 호출을 담당하는 Service를 역할(endpoint)에 따라 분류하여 중복을 최소화함.
#241

싱글톤 객체에서 의존성 주입을 통한 레이어 분리
싱글톤 객체로 구현되어있던 Service객체는 의존성이 강하게 결합되고 테스트가 어려워지며 유지 보수가 어려워 DI주입을 통한 레이어 분리를 도입
Manager 도입
역할에 따라 서비스를 분리하고나니 한 VC에서 여러 개의 Service를 필요로 하는 경우가 생겨 각 Service를 관리하기 위해 Manager 클래스를 도입. Manager 클래스는 해당 화면이 필요로 하는 Service들을 생성하고 관리하는 ServiceWrapper 역할을 함. Manager 도입을 통해 각 Service의 역할을 명확히 구분하고 중복을 최소화하여 유지보수성을 향상시킬 수 있음.
[Manager 객체와 Service 객체 역할]
Manager 객체
에서는 네트워크 결과로 얻게 될 DTO를 앱에서 사용될Model
로 바꿔주는 역할 수행🔫 PR Point
📸 스크린샷
📮 관련 이슈