이번 포스트에서는 사용자가 화면으로 볼 수 있는 view가 실제로 어떤 과정에 의해 형성되는지 알아봅니다. 또한, 이 과정에서 iOS.13버전에 어떠한 변화가 생겼는지 설명합니다. 이 부분을 아는 것이 중요한 이유는 가끔 app이 최초 실행 될 때 죽는 경우가 발생할 수 있는데 view가 최초에 형성되는(앱이 최초 실행되는) 과정을 알면 문제를 해결하는데 도움이 될 수 있기 때문입니다.
View의 가장 최상위 계층에 있는 것이 바로 window입니다. window는 UIWindow의 instance입니다. window는 모든 view의 가장 위에 존재하는 superView라고 이해하시면 됩니다.
rootView는 window의 속성 중 하나입니다. 사용자가 실제로 볼 수 있는 화면은 rootview의 위에 생성한 View들입니다.
app이 실행되면 UIApplicationMain 함수가 호출됩니다.(Objective-C project와는 달리 Swift에서는 코드로 직접적으로 호출하지 않아도 됩니다.) 이 함수는 app이 구동되는데 가장 기초적이고 중요한 인스턴스들을 생성합니다. 이 중에 window와 rootView가 포함됩니다.
UIApplicationMain 함수(이후 main 함수라 하겠습니다.)가 실행되면서 UIApplication이 인스턴스화되고 이어서 app delegate class들이 인스턴스화됩니다. UIApplication은 singlton을 선언하고 있기 때문에 UIApplication.share를 통해 해당 인스턴스에 접근할 수 있습니다.
main함수는 Info.plist에서 storyboard 사용여부를 확인하고 사용하고 있다면(UIMainStoryboardFile로 식별) storyboard로viewController를 인스턴스화 합니다.
main함수는 UIWindow를 인스턴스화해서 app delegate의 window속성에 할당합니다. 그리고 이 window속성의 rootViewController에 main storyboard를 할당합니다.
위의 작업이 모두 끝나면, main함수는 app delegate의 application(didFinishLanuchingWithOptions:)함수를 호출합니다.
window와 rootViewController가 정의 되었지만 이 단계에서 아직 화면은 보이지 않습니다. 화면을 보이도록 하기 위해 app delegate에 있는 window 속성을 'key window'로 지정해주어야 합니다. 이를 위해 main함수는 window의 인스턴스 메소드 'makeKyeAndVisible'를 호출합니다.
만약 여러분이 storyboard를 사용한다면 위의 과정은 main함수가 알아서 해주지만, storyboard를 사용하지 않는 경우 위 과정을 AppDelegate.swift 파일에서 직접 code로 구현해야 합니다.
iOS 12버전과 마찬가지로 main함수가 UIApplication과 app delegate class를 인스턴스화 합니다.
그리고는 12버전과 달리 이전 작업을 하지 않고 곧장application(didFinishLanuchingWithOptions:)메서드를 호출합니다.
위 함수가 호출 된 후에 main함수는 UISceneSession, UIWindowScene, window scene delegate를 인스턴스화 합니다.
scene delegate의 class는 Info.plist의 Application Scene Manifest안에 Scene Configuration에서 확인할 수 있습니다.
main함수는 Info.plist의 Application Scene Manifest안에 있는 Scene Configuration에서 storyboard의 이름을 확인하여 storyboard 사용여부를 확인합니다. 만약에 값이 있다면 storyboard를 시작 viewController로 인스턴스화 합니다.
main함수는 UIWindw를 인스턴스화 하고 이를 scene delegate의 window 프로퍼티에 할당합니다.
이후 main함수는 시작 view controller로 인스턴스화 했던 Main storyboard를 window의 rootViewController로 할당하고 makeKeyAndVisible 메서드를 호출하여 'key window'로 지정하고 화면에 보여줍니다.
이후 scene delegate의 scene(willConnecTo:options:) 메서드가 호출됩니다. 이 메서드를 통해 우리는 launch process가 끝난 직후 화면이 보이기 전에 해야할 작업을 구현할 수 있습니다. 예를 들면, window가 제대로 설정되었는 지 확인할 수 있습니다.
iOS 12번과 다른 점은 application(didFinishLanuchingWithOptions:)메서드를 훨씬 일찍 호출한다는 점입니다.
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
self.window = UIWindow(windowScene: windowScene)
let vc = // ...
self.window!.rootViewController = vc
self.window!.makeKeyAndVisible()
}
}
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
self.window = UIWindow(windowScene: windowScene)
let userHasLoggedIn : Bool = // ...
let vc = UIStoryboard(name: "Main", bundle: nil)
.instantiateViewController(identifier: userHasLoggedIn ?
"UserHasLoggedIn" : "LoginScreen") // *
self.window!.rootViewController = vc
self.window!.makeKeyAndVisible()
}
}