정말 억울한일을 당했다. 분명 잘 되던 내 애지중지 앱이 대표님 앞에서 먹통이 되어버렸다. 이때 너무 충격 받아서 머리가 지근지근 했음.
잘 되던 앱이 Airplay로 대표님 앞에서 시연하자마자 앱이 망가져버렸다. Airplay를 안하면 문제가 생기지 않고, 연결하자마자 문제 생기고 난리 났었음.
호흡을 가다듬고 하나하나 문제점을 찾으러 올라가다보니 문제점을 찾을 수 있었다.
이때의 가장 큰 공포는 왜 되는지 모르고 왜 안되는지 모르는게 가장 큰 공포였음... 될때도 있고 안될때도 있었기 때문.
func changeRootView<Content: View>(to view: Content) {
// 현재 활성화된 SceneDelegate 가져오기
guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let sceneDelegate = scene.delegate as? SceneDelegate,
let window = sceneDelegate.window else {
print("SceneDelegate 또는 window를 찾을 수 없음")
return
}
// 새로운 RootView 설정
window.rootViewController = UIHostingController(rootView: view)
window.makeKeyAndVisible()
}
방금 내가 GPT에게 짜달라고 한 코드임.
이 코드의 문제점은 다음과 같다.
iOS 프로젝트에서 굳이 뭐 다른거 하지 않는 이상 UIScene이 2개 이상 생길일이 거의 없다.
애초에 개발자인 우리가 UIScene이 한개 만들었으니까 한개 이상 생길일이 있나? 싶다. 그래서 .first를 써도 아에 문제가 없을지도 모른다.
하지만 이 사진을 보자. UIWindowScene이 두개다.
name을 보면 알수있다. Info Pilist에도 SceneDelegate 관련 설정을 보면 Default Configuration 이라는 이름으로 정의해둔걸 볼 수 있다. 따라서 첫번째 Scene의 이름도 Default Configuration이라는 이름으로 존재한다.
두번째는 Airplay 뭐시기 적혀있고, 심지어 delegate는 nil임.
그렇다. Airplay를 하면 UIScene이 두개가 된다. 꼭 Airplay가 아니고 C to HDMI로 연결해도 Scene에 Airplay라는 이름으로 두개가 된다.
https://github.com/feedfm/Airplay2ndScreen이 깃헙 들어가 보면 이점을 이용해서 단순 미러링이 아닌 또 다른 Display로 사용하는 예제도 있다.
다시한번 돌이켜보면
심지어 우리가 무심코 .first로 지나갔던 UIApplication.shared.connectedScenes는 다음과 같다.
자료형이 Set이다.
.first를 조지면 매번 우리의 원래 UIScene이 나올지, Airplay로 나온 UIScene이 될지 모른다.
거기에 우리는 as? SceneDelegate로 우리의 신딜리게이트로 형변환을 시도한다. Airplay로 만든 친구는 우리가 만든게 아닐 뿐더러 신딜리게이트가 없어서 형변환에 실패하게되고 코드는 실행되지 않는다.
GPT가 짜준다고, 남들이 다 그렇게 한다고 무조건 그게 정답은 아님. 내가 알기론 새싹 다른 사람들도 RootView 바꿀때 저렇게 바꿀텐데, 무조건 문제 생길듯.
지나가던 새싹 사람 흠칫하고 갑니다