-
Notifications
You must be signed in to change notification settings - Fork 26
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
날씨앱 [STEP 2] hyujin #42
base: rft_3_hyujin
Are you sure you want to change the base?
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.
포팅하느라 고생 많으셨어요!
뷰 - 뷰모델의 역할에 대해 코멘트 드린 내용 확인 부탁드려요!
viewModel.process(.loadView) | ||
bindingView() |
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.
loadView 시점에는 self.view를 갈아끼는 행동 이외에 다른 행동은 지양해주세요!
viewModel과 view를 바인딩하는 시점은 viewDidLoad에서 수행하는걸 권장합니다!
init(api: WeatherServiceable) { | ||
self.api = api | ||
viewModel = WeatherViewModel(api: api) |
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.
뷰모델 또한 생성자 주입으로 받으면 좋을 거 같아요!
|
||
private var weatherView: WeatherView? | ||
private var api: WeatherServiceable | ||
let viewModel: WeatherViewModel |
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.
let viewModel: WeatherViewModel | |
private let viewModel: WeatherViewModel |
await fetchWeatherAPI() | ||
refreshControl.endRefreshing() | ||
private func bindingView() { | ||
view = viewModel.view |
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.
뷰모델은 뷰에 관한건 알지 못하는게 좋아요!
즉 뷰를 만들고, 어떤 뷰가 생성/삭제되는지는 뷰컨에서 수행하고,
뷰모델은 비지니스 로직을 수행해서 어떠한 상태를 변경하는 행위만 해주세요
@Published var view: WeatherView? | ||
@Published var cityName: String? | ||
@Published var currentUnitTitle: String? | ||
|
||
@Published var didSelectAction: ((WeatherForecastInfo, City) -> Void)? | ||
@Published var networkErrorMessage: 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.
private(set)을 붙여주면 좋을 것 같아요!
// Created by Hong yujin on 4/25/24. | ||
// | ||
|
||
import UIKit |
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.
극단적으로 뷰모델 파일에는 UIKit을 import하면 안된다고 생각해주세요
case refresh | ||
} | ||
|
||
private let refreshControl: UIRefreshControl = UIRefreshControl() |
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.
요친구는 뷰컨으로 가서 뷰컨에서 addView, autolayout을 잡고,
refresh가 땡겨졌는지에 대한 행동을 뷰컨에서 탐지해서 뷰모델로 올려주세요!
|
||
private let refreshControl: UIRefreshControl = UIRefreshControl() | ||
|
||
@Published var view: WeatherView? |
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.
요친구도 뷰컨으로!
private func loadView() { | ||
view = WeatherView(delegate: self) | ||
|
||
refreshControl.addTarget(self, | ||
action: #selector(refresh), | ||
for: .valueChanged) | ||
|
||
view?.setTableViewRefreshControl(refreshControl: refreshControl) | ||
} |
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 -> viewcontroller -> viewmodel
상태 변경: viewmodel -> dependency(네트워크, 복잡한 로직을 처리하는 어떤 객체 - 템프 유닛, 타이머, 데이터베이스 등등) -> viewmodel 상태 변경
상태 관찰: viewmodel -> viewcontroller -> view
요런 순서로 진행된다고 보심 될 거 같아요
|
||
private func fetchWeatherAPI() async { | ||
do { | ||
let weatherJSON = try await api.fetchWeatherJSON() |
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에서 온 resposne를 viewcontroller에 퍼블리시 -> 뷰컨에서 옵져빙 -> 뷰의 상태 변경
@havilog
STEP2 부분은 기존 STEP1이랑 많이 겹치는 것 같아
화씨/섭씨 변경과 MVVM 구조 변경을 중점적으로 리팩토링하였습니다.
조언을 얻고 싶은 부분
ViewController과 View, ViewModel 사이의 바인딩을 제대로 한것인지,
ViewModel에는 비즈니스로직, View와 ViewController는 UI 로 나름 구분하여 개발하였으나, refreshControl의 위치가 모호하였습니다.
또,
WeatherView
를 ViewModel이 갖고있다보니 UITableViewDelegate>didSelectRowAt이 호출되면WeatherView에서 WeatherViewModel 그리고 WeatherViewController로 액션을 넘겨주는 구조로 짜게 되었는데 이것이 쓸데없는 여러 과정을 거치는 것이 아닌가 하는 생각도 듭니다.
구현한 부분을 확인하고 조언 부탁드리겠습니다!