Weekoding
[Swift] 생명주기 정리( App / ViewController ) 본문
기기에 맞추어 constraint를 변경한다거나,
데이터를 불러와서 setting할 때,
화면 혹은 앱이 끝나서 데이터를 처리하거나
background에서 처리할 것이 있을 때(금융 앱들은 정보보호 차원으로 화면이 가려지는 등)
생명주기를 잘 알고 대응해야 적절한 타이밍에 작업을 할 수 있다.
App과 ViewController의 LifeCycle에 대해 정리해 보자.
🔄 App LifeCycle
우선, App LifeCycle과 관련된 동작들은 SceneDelegate와 AppDelegate에서 이루어진다.
Xcode Project를 생성하면 기본적으로 생성이 되어있는 파일들이다.
Before start :
iOS 12 이하 - AppDelegate가 모든 역할을 담당했다.
iOS 13 이상 - Scene이라는 개념이 도입되어 SceneDelegate가 등장하게 되었다.
12 이하일 때는 하나의 앱이 하나의 Window를 가진다는 개념이었다.
그러나 13부터 Window의 개념이 Scene으로 대체되고, 하나의 앱은 여러 Scene을 가질 수 있게 되었다.
포스팅 시점은 iOS 15 까지 등장한 상태이지만,
Legacy 코드를 접할 수 있으므로 해당 변경사항을 숙지하고 각 파일들의 역할과 메소드를 짧게 알아보자.
AppDelegate:
- App의 데이터 구조 초기화
- App의 Scene에 대한 Configuration( 환경설정 )
- App 밖에서 오는 알림에 대응( ex: 배터리 부족, 다운로드 완료 )
- App 자체를 targeting하는 이벤트에 대응( 특정 View, ViewController, Scene ❌ )
- 실행시 요구되는 Service 등록( ex: Apple Push Notification Center )
- SceneSession을 통해 Scene에 대한 정보를 업데이트 받는다.
SceneSession: Scene 고유의 런타임 인스턴스를 관리. 고유 식별자와 Scene의 세부 구성사항이 들어있다.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
= 이 곳에서 App 자체에 대한 각종 setup을 진행. launch시 호출
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
= App launch가 아닌, 새로운 scene/window를 제공할 때 불리는 메소드.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
= 사용자가 scene을 폐기할 때 호출되는 메소드.
}
위 세가지 메소드는 프로젝트 생성 시 AppDelegate에 기본적으로 구현되어 있는 메소드들이다.
다음 메소드들은 사용자가 필요에 따라 작업을 구현할 수 있는 메소드들이며, App LifeCycle과 관련이 있다.
func applicationWillEnterForeground(_ application: UIApplication) {
//Application이 Foreground로 진입하는 상태
}
func applicationWillResignActive(_ application: UIApplication) {
//Application이 Background로 진입하는 과정 중 일부로,
//Active상태를 벗어날 때를 의미한다. 이때, inActive상태를 거쳐간다.
}
func applicationDidEnterBackground(_ application: UIApplication) {
//Application이 Background로 진입하는 상태.
//앱이 종료된 것은 아니며, 메모리를 차지하고 있다. 마무리 작업을 한다.
//전화가 올 때처럼 interrupt에 의해 Background로 진입할 수 있다.
}
func applicationDidBecomeActive(_ application: UIApplication) {
//Background상태에서 다시 Active상태가 될 때를 의미한다.
//이때, inActive상태를 거쳐간다.
}
func applicationWillTerminate(_ application: UIApplication) {
//Background상태에서 메모리를 반납하고 종료된다.
//너무 오래 Background상태에서만 머물고 있으면 OS에 의해 Terminate 된다.
}
SceneDelegate:
iOS13 이후의 개념으로, UI의 상태를 알 수 있는 UILifeCycle을 관리하는 역할(AppDelegate로부터 넘겨받은 셈)
scene의 LifeCycle 순서에 맞추어 정리하였다.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
= 새로운 UIWindow를 생성하여 scene에 연결하고, rootViewController를 설정.
Storyboard를 사용하면 자동으로 초기화 되며, 그렇지 않을 때는 이곳에서 추가 설정이 필요.
보통 code로 UI를 짤 때, 첫 view를 만들 때 쓰임.
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
= scene이 background → foreground(혹은 처음 active)로 전환될 때 호출되는 메소드.
background상태로 돌입할 때의 변화들을 다시 원상복귀 시키는 작업을 한다.
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
= inactive → active상태로 scene이 돌입할 때 호출되는 메소드
scene이 inactive되면서 멈춰있었던 작업들은 다시 시작하는 작업을 한다.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
= scene이 active → inactive 상태로 빠질 때 호출된다
추가로, 이러한 전환은 interrupt에 의해 일어날 수 있다(ex) 전화가 왔을 때)
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
= scene이 foreground → background 상태로 돌입할 때 호출된다.
data를 저장하고, 공유 중이던 자원을 돌려주거나
다시 scene이 foreground로 돌입할 때 필요한 data들을 처리하는 작업을 한다.
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
= scene이 폐기되거나 background상태에 들어갈 때 호출되는 메소드.
scene이 사용하던 자원을 돌려주는 작업을 한다.
scene은 폐기될 필요가 없다면 다시 연결될 수 있다.(disconnect는 app 종료와는 다른 개념임.)
}
- Unattached : scene이 연결되지 않은(unattached) 상태
- Active : App이 실행중이며 이벤트를 받은 상태
- Inactivive : App이 실행중이며 이벤트를 받지 않은 상태
- Suspended : Background에 있고, 실행되는 code가 없는 상태
🔄 ViewController / View LifeCycle
한눈에 LifeCycle을 파악할 수 있는 사진을 발견했다.
보는 바와 같이 View자체의 상태는 4가지로 나눌 수 있고, 관련된 메소드는 총 6가지이다.
View의 상태(4가지)
- Appearing
- Appeared
- Disappearing
- Disappeared
영단어 의미 각각 그대로 보여지는 상태 • 보여진(완료된) 상태 • 사라지는 상태 • 사라진(완료된) 상태이다.
View의 상태에 관한 메소드(6가지)
View 상태에 따라 ViewController에서 호출되는 메소드가 다르다.
viewDidLoad()
- View가 메모리에 로드될 때 호출되는 메소드. 따라서 처음 생성될 때만 한번 호출된다.
- 이 곳에서 ViewController의 setup을 구현한다.
viewWillAppear()
- View가 화면에 보여지기 시작할 때(View 계층에 추가되기 전에) 호출되는 메소드. 따라서 여러번 호출될 수 있다.
- 이 곳에서 보여지지 않다가 보여질 때, Update가 필요한 부분들을 구현한다.
viewDidAppear()
- View가 화면에 보여진 후(View 계층에 추가된 후) 호출되는 메소드.
- 이 곳에서 View가 화면에 보여지자 마자(사용자가 화면을 마주한 직후) 처리할 부분들을 구현한다.
viewWillDisappear()
- View가 화면에서 사라지기 시작할 때(View 계층에 제거되기 전) 호출되는 메소드.
- 이 곳에서 View가 사라지기 전 작업내용을 Rollback하거나, data를 저장하는 부분을 구현한다.
viewDidDisappear()
- View가 화면에서 사라진 뒤(View 계층에서 제거된 후) 호출되는 메소드.
- 이 곳에서 View가 사라지는 것과 관련된 작업들을 구현한다.
- View는 사라졌지만 메모리에서 삭제된 것은 아니다.
정리 📌
App LifeCycle:
Scene LifeCycle을 관리하는 SceneDelegate와
App 단위의 설정을 관리하거나 Event에 대응하는 AppDelegate로 관리가 된다.
ViewController / View LifeCycle:
View의 상태를 appearing, appeared, disappearing, disappeared의 4가지로 정의하고,
이에 따라 ViewController가 6가지의 메소드를 호출하여 LifeCycle 관리가 이루어진다.
오류 및 지적사항은 댓글로 남겨주시면 감사하겠습니다!
참고 :
https://sueaty.tistory.com/134
https://velog.io/@dev-lena/iOS-AppDelegate%EC%99%80-SceneDelegate
https://velog.io/@delmasong/Understand-the-View-Controller-LifeCycle
'공부 노트(Swift)' 카테고리의 다른 글
[Swift] HTTP 접근 허용하기(App Transport Security) (0) | 2022.07.26 |
---|---|
[Swift] weak self, guard let self = self, self?. (0) | 2022.06.06 |
[Swift] ViewController간 데이터 주고받기 - Delegate pattern (4) | 2022.05.12 |
[Swift] lazy Variable (0) | 2022.05.04 |
[Swift] UIKit코드로 SwiftUI Preview 사용해 보기 (0) | 2022.05.03 |