드디어 프로젝트가 끝났다.
새벽까지 팀원들이랑 열심히 했는데 기획에 너무 욕심을 부린건지.. 생각보다 기획했던 기능을 많이 구현하지 못해 아쉬움이 많이 남는다.
그래도 그와 별개로 UI를 좀 예쁘게 잘 만들지 않았나..싶어 만족스럽다.
외부 API도 많이 이용해볼 수 있어 재밌는 프로젝트였다.
네이버 지도 API 공식문서가 (개인적으로는) 굉장히 친절해서 크게 어렵지 않게 활용할 수 있었다.
주말동안 피드백을 반영한 리팩토링과 아쉬운 기능 구현등을 진행해보려 한다.
앱 실행 시, ViewModel -> View로 데이터를 바인딩하기 위한 클로저가 간헐적으로 실행되지 않는 현상이 발생했다.
ViewModel에서 데이터는 정상적으로 변경했는데 View로 바인딩되지 않아 UI가 업데이트 되지 않았다.
앱을 껐다 켜면 정상 작동되는 경우도 있는데 어느 때에 작동이 되고 어느 때에 안되는지를 찾을 수 없었다. (개행만 한번 했는데 정상 작동하는 경우도 있었다.)
지도 뷰에서 동물 마커 클릭 시 시트 VC를 띄운다.
이 과정에서 시트 VC에 지도뷰에서 사용하던 VM을 매개변수로 전달하고 있었다.
우선 여기서 첫 번째 문제점이 발생한다.
VM은 클래스이므로 내부 속성을 참조한다.
시트VC와 지도VC에서 동일한 VM을 사용하게되면 동일 속성에 동시에 접근할 수도 있어 데이터 무결성이 저해된다.
그리고 두 번째가 직접적인 원인인데, 시트 VC 내에서 VM의 바인딩 클로저를 재정의하고 있었다.
즉, 첫 번째 문제점이라 말했던 현상이 발생해버린 것이다.
VM의 stateChanged라는 클로저를 지도VC에서 정의해두었는데, 시트VC에서 다시 정의해버린 것이다.
구현 당시에는, VM에는 여러 케이스의 State가 존재하고, stateChanged는 각 케이스마다 동작을 정의하니 지도VC에서 정의한 케이스의 동작은 두고 시트VC에서 나머지 케이스의 동작을 정의하면 되겠다고 생각했다.
그러나 시트VC에서 stateChanged 클로저를 정의하는 순간 의도와는 달리 이미 정의된 케이스의 동작들의 연결이 약해진 것이다.
(아예 없어지는 경우도 있지만, 간혹 이미 정의된 동작이 그대로 존재했다. 그래서 동작이 되었다가 안되었다가 한 것이다.)
일단 프로젝트 제출이 급했기 때문에 시트VC가 해제될 viewWillDisappear 시점에 지도VC를 가져와서 바인딩하는 함수를 재호출 하였다.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// 계층 구조를 거슬러 mapVC를 꺼내옴
guard let tabBar = presentingViewController as? UITabBarController,
let nav = tabBar.selectedViewController as? UINavigationController,
let mapVC = nav.topViewController as? MapViewController
else { return }
mapVC.bindingData()
}
급한 불은 껐지만 여전히 간헐적으로만 실행되는 동작이 존재했다.
등록 동물을 삭제해도 마커가 사라지지 않았다.
현재 구조는 여전히 시트VC가 VM을 주입받아 사용하고 있다.
앞서 말했듯 이는 데이터의 무결성을 낮추는 원인이 될 수 있다.
따라서 지도VC와는 별도의 VM을 생성하여 사용하는 방향으로 리팩토링 예정이다.