회사업무를 진행하며 화면계층을 구성하던 중, whose view is not in the window hierarchy 라는 런타임 에러메세지를 만나 해결하였다.
심폐음 측정ViewController에서 심폐음 측정이 완료되면 환자를 선택하기 위한 측정대상ViewController를 fullScreen으로 present 시켰다.
그리고 측정대상ViewController에서 측정대상이 없을 경우, 새롭게 환자를 추가하기 위해 환자추가버튼을 누르면 환자추가ViewController가 default 스타일로 present 되도록 구성했었다.
(예시)
하지만, 환자추가버튼을 누르니 환자추가ViewController가 나타나지 않고 whose view is not in the window hierarchy 에러가 나타났다.

해당 에러의 원인은, 측정대상 ViewController와, 환자추가 ViewController가 동일한 ViewController에서 present 되려 했기 때문에 화면계층이 올바르지 않아 동작하지 않았다는 것.
위와 같은 오류를 발생시킨 이유는, 프로젝트에서 Coordinator 패턴을 적용해 사용했는데 start()메소드에서 측정대상, 환자추가ViewController 모두 심폐음측정ViewController에서 전달받은 navigationController에서 present했기 때문이였다.
// 측정대상 Coordinator
class 측정대상Coordinator {
let navigationController: UINavigationController
...
func start() {
let 측정대상VC = 측정대상ViewController()
측정대상VC.modalPresentationStyle = .fullScreen
// 같은 navigationController에서 present!!
navigationController.present(측정대상VC, animated: true)
}
}
// 환자추가 Coordinator
class 환자추가Coordinator {
let navigationController: UINavigationController
...
func start() {
let 환자추가VC = 환자추가ViewController()
// 같은 navigationController에서 present!!
navigationController.present(측정대상VC, animated: true)
}
}
위와 같은 문제가 발생하게 된 원인은 다음과 같다.
측정 전 선택된 환자가 있을 시,
측정ViewController->결과ViewController
선택된 환자가 없을 시,
측정ViewController->측정대상ViewController->결과ViewController
이러한 화면 로직 때문에, 측정대상ViewController를 NavigationController에 push로 띄우게 된다면, 측정대상Coordinator는 본인에게 필요하지 않은 측정데이터를 가진 상태에서 결과Coordinator를 띄워야 했었다. 또한 측정대상Coordinator는 다른 화면계층에서 측정데이터가 필요하지 않는 상황에 재사용되야 했기 때문에 더욱 측정데이터가 필요하지 않았다.
따라서, 측정대상Coordinator와 결과Coordinator간 데이터를 전달하는 방식이 되지 않도록 측정ViewController에서 측정대상ViewController을 fullScreen 타입으로 present해 환자데이터를 선택하도록 한다. 원하는 환자가 없을 경우, 환자추가ViewController를 다시 present해 새로운 환자를 추가하게 한다. 환자가 선택되면 dismiss한 다음 환자데이터를 측정Coordinator에 전달하도록 하고 결과ViewController를 측정데이터와 환자데이터를 함께 전달하고자 하는 목적이 있었다.
측정대상ViewController을 fullScreen 스타일로 present시키지 않고, push로 화면을 띄운 다음, 환자가 선택되면 pop해주고 측정ViewController에서 다시 결과ViewController를 push해주는 방식으로 변경해 해결하였다.

(도움을 얻은 글 : https://velog.io/@ellyheetov/errorhandling01)