← Lab
Application 실행 구조
스터디2025.06.25
- UIKit
- Swift
Application 실행 구조

프로세스 시작 (엔트리 포인트)
main()이 실행되면서 Swift/Objective-C 런타임이 초기화
@UIApplicationMain(과거 방식)혹은@main(Swift 5.3+)이 엔트리 포인트를 직접 지정하여 내부적으로UIApplicationMain을 호출
UIApplicationMain이UIApplication객체와AppDelegate 인스턴스를 생성하여 메인 런루프 시작
Scene 구성 (Info.plist와의 연계) iOS 13+
- 시스템은 새로운 씬이 필요할 때
application(_:configurationForConnecting:options:)를 호출한다. - 반환한
UISceneConfiguration또는Info.plist의Scene Manifest를 활용해 씬을 만든다. - Info.plist에
UIApplicationSceneManifest이나UISceneConfigurations가 있으면 해당 구성을 우선적으로 참조한다. - AppDelegate 메서드를 구현하면 커스텀 로직으로 구성을 선택할 수 있다.
실행(런치) 유형
- Cold Launch : 가장 무거운 유형으로, 프로세스가 없던 상태에서 처음 기동되는 실행 유형을 뜻한다.
- Warm Launch : 백그라운드에서 중단 혹은 종료되지 않은 상태에서 다시 진입할 경우를 말한다. (상대적으로 가볍다.)
- Background Launch : 푸쉬 처리, 백그라운드 작업 등으로 보이기 않게 기동되는 것을 말한다.
Cold Launch의 단계별 호출 순서 (UIKit + Scenes)
- 프로세스 시작 및 런타임 초기화
@main엔트리 포인트로 UIApplicationMain에 진입- UIApplication 및 AppDelegate 인스턴스 생성
- AppDelegate 1회 세팅
application(_:didFinishLaunchingWithOptions:)이 실행되며 앱 전역 초기화를 진행한다.- 로깅, 분석, DI 컨테이너 빌드, 서드파티 SDK 등록, 기본 설정 등을 수행한다.
- UI 생성은 하지 않는다.
- Scene 세션 구성
- iOS 13 이상에서
application(_:configurationForConnecting:options:)을 호출시켜 새로 연결될 Scene의UISceneConfiguration을 반환하여 클래스나 스토리보드를 지정한다.
- Scene 연결 (화면 준비)
- SceneDelegate에서
scene(_:willConnectTo:options:)를 통해 UIWindow를 생성하거나 컴포지션 루트를 설정한다. - Window는
makeKeyAndVisible()을 활용! - 스토리보드를 사용하면 시스템이 직접 VC를 만든 뒤 해당 메서드에서 후처리한다.
- Foreground 전이 및 활성화
sceneWillEnterForeground(_:)다음으로sceneDidBecomeActive(_:)이 실행되며 앱이 최종적으로 Active 된다.
🤔 의존성 주입을 어디서 해야할까?
의존성 주입을 위한 Composition Root는 어디가 좋을 지 한 번 찾아보았다.
- 앱 단위의 전역 단위라면?
- AppDelegate의
application(_:didFinishLaunchingWithOptions:)가 좋다. - 여기서 로깅, 분석, 환경 설정 혹은 DI 컨테이너 생성 및 공유 객체를 등록하는 것도 좋을 것 같다.
- UI나 화면 단위(씬 단위) 라면?
- SceneDelegate의
scene(_:willConnectTo:options:)가 좋다고 한다. - UIWindow와 RootVC 생성 직전에 ViewModel이나 Usecase, 레포지터리 등을 주입할 수 있다.
- SceneDelegate → RootVC → ChildVC로 이어지는 트리의 최상단에서 주입하면 하위로 깨끗하게 전파할 수 있기 때문이다!
- 스토리보드를 사용한다면?
- 똑같이 씬 델리게이트에서
scene(_:willConnectTo:options:)에서 스토리보드가 만든 RootVC를 캐스팅하여 의존성을 세팅하는 방법도 있다.
🤔 그렇다면 SceneDelegate에서 자식 VC까지 직접 접근해 주입해도 괜찮은가?
추후 테스트에 용이하거나.. 유지보수 측면으로 바라본다면 RootVC에서 의존성을 모아 주입하는 게 좋지 않을까싶다.
SceneDelegate에서 주입하게 되면 결합도가 올라가지 않을까?
💡 공식문서에서 언급되는 흔한 실수와 Best Practice
- UIWindow/RootVC를 AppDelegate에서 만들지 않기(iOS 13+)
- 씬 기반에선 SceneDelegate가 UI 책임을 지는 구조가 좋다.
- 무거운 작업을 런치에 넣지 않기
- didFinishLaunching에서 동기 네트워크/대용량 I/O 하지 않기.
- 초기 화면이 늦어질 수 있다.
- 상태 복원/유지 전략
- 첫 런치 시 한 번만 필요한 설정은 AppDelegate에서,
- 사용자 UI 복원은 Scene 단위에서 진행하자!
- 멀티씬 고려 전략
- iPad/외부 디스플레이, Stage Manager 등에서 씬이 여러 개 생길 수 있으므로 씬마다 독립 상태 관리를 해야한다!
핵심 정리
- AppDelegate(앱단위)
- 프로세스 기동 및 1회성 초기화
- Scene 구성의 진입점
- SceneDelegate(씬, 윈도우 단위)
- UIWindow와 RootVC 설정
- Active와 Background 전환 처리 담당
- Application Lunch Flow 핵심
- 프로세스 부팅
- AppDelegate 초기화
- (iOS 13+) Scene 구성 및 연결 진행
- UIWindow와 RootVC 생성 및 연결
- 앱 Foreground 및 Active 처리
- 실행 플로우 다이어그램 (생성은 GPT가 했습니다.)
[Process Start]
|
v
UIApplicationMain ---> AppDelegate 인스턴스 생성
|
v
application(_:didFinishLaunchingWithOptions:)
(전역 초기화/DI/로그 설정)
|
v
application(_:configurationForConnecting:options:)
(새 Scene 구성 반환)
|
v
scene(_:willConnectTo:options:)
(UIWindow 생성, RootVC 설정, makeKeyAndVisible)
|
v
sceneWillEnterForeground -> sceneDidBecomeActive
(보이기 직전) (사용자 입력 가능)
참고 자료
About the app launch sequence | Apple Developer Documentation
Responding to the launch of your app | Apple Developer Documentation
Managing your app’s life cycle | Apple Developer Documentation
application(_:didFinishLaunchingWithOptions:) | Apple Developer Documentation