날씨 앱 뷰에 데이터가 갱신되지 않는 문제해결
날씨 앱 뷰에 데이터가 갱신되지 않는 문제해결
날씨 앱이 날씨 데이터를 받아오고 뷰에 보여야 하는데 보였다가 안 보였다가 할 때가 있습니다. 😱 어디가 문제인지 브레이크포인트를 걸면서 찾아보았습니다.
의심이 가는 부분은 뷰 생성 시점과 뷰 바인딩 시점 그리고 데이터 수신 시점이 있는데 여기서 무언가 순서가 잘못되었나 싶었습니다. 🤔
먼저 뷰모델을 생성하는 시점입니다. 뷰모델은 뷰 컨트롤러를 초기화할 때 생성하게 되어있습니다. 그리고 viewDidLoad() 단계에서 뷰를 바인딩합니다.
final class WeatherViewController: UIViewController {
// 뷰모델 생성
private var weatherViewModel = WeatherViewModel()
override func viewDidLoad() {
super.viewDidLoad()
// 데이터 바인딩
bindingViews()
}
...
}
뷰모델에서는 초기화할 때 데이터를 요청합니다.
final class WeatherViewModel {
...
init() {
// 현재 날씨 데이터 요청
fetchCurrentWeatherData()
// 시간별 예보 날씨 데이터 요청
fetchForecastWeatherData()
}
...
}
위 코드를 보면 뷰모델이 초기화하는 과정에서 데이터를 요청합니다. 그리고 바인딩은 viewDidLoad() 단계에서 수행합니다. 그러면 메서드 호출 순서가 다음과 같이 됩니다.
뷰모델 생성 -> 날씨 데이터 요청 -> 뷰 생성 -> 뷰 바인딩 순으로 호출됩니다.
분석하면서 뭔가 호출 순서가 잘못되었다고 느꼈습니다. 뷰를 생성하거나 바인딩을 하지 않았는데 데이터를 요청하고 있습니다. 만약에 날씨 데이터가 뷰 생성과 뷰 바인딩이 이뤄지기 이전에 도착하면 뷰를 갱신할 수 없게 됩니다. 따라서 메서드 호출 순서는 다음과 같이 변경되어야 합니다.
뷰모델, 뷰 생성 -> 뷰 바인딩 -> 날씨 데이터 요청 순으로 호출하면 뷰가 생성되고 바인딩 되었다는 것이 보장되기 때문에 뷰가 제대로 갱신되리라 생각합니다.
앱을 실행하자마자 데이터를 요청하고 뷰에 반영해야 하므로 데이터 요청 시점을 viewDidLoad()에서 뷰 바인딩 이후에 호출하도록 개선해볼 수 있습니다.
뷰모델에서는 초기화 과정에서 데이터를 요청하는 구문을 제거하고 별도의 데이터 요청 메서드 loadWeatherData()
를 만들었습니다. 이 메서드는 뷰 컨트롤러에서 뷰 바인딩 이후에 호출하도록 합니다.
final class WeatherViewModel {
...
func loadWeatherData() {
fetchCurrentWeatherData()
fetchForecastWeatherData()
}
...
}
뷰 컨트롤러에서는 메서드 호출 순서를 변경하였습니다. (뷰모델에서 새로 작성한 메서드 호출)
final class WeatherViewController: UIViewController {
// 뷰모델 생성
private var weatherViewModel = WeatherViewModel()
override func viewDidLoad() {
super.viewDidLoad()
// 뷰 바인딩
bindingViews()
// 날씨 데이터 요청
weatherViewModel.loadWeatherData()
}
...
}
위와 같이 변경하니까 더는 뷰가 안 보이는 경우가 발생하지 않았습니다. 같은 문제가 발생하지 않도록 앞으로도 생성 순서, 초기화, 메서드 호출 순서를 잘 고려하여 작성할 수 있도록 노력해야겠습니다. 😎
댓글남기기