앱의 생명주기(Life Cycle)
앱의 생명 주기란 개념이 왜 필요할까?
아이폰 앱 게임 중 ➡ 전화 옴 ➡ 앱은 자동으로 “통화화면으로” 전환 (실행중이던 앱은? 잠시 비활성화 상태로..)
게임 중이던 모든 데이터는? 저장이 안되서 날아갈 수도 있음
앱의 실행(메모리에 올라감)부터 ➡ 앱이 백그라운드로 / 앱의 종료까지를 포괄적으로 표현하는 개념
앱의 실행이 시작되서, 앱이 종료(메모리에서 내려감)되기까지의 주기가 존재
즉
앱의 생명 주기 ➡ 앱의 비활성화 / (다른앱으로 또는 백그라운드로)전환 / 종료 시점을 파악하기 위함
앱의 생명주기는 크게 보면 아래와 같다
- Not Running: 앱이 실행되지 않은 상태
- Inactive: 앱이 실행중인 상태. 그러나 아무런 이벤트를 받지 않는 상태
- Active: 앱이 실행중이며, 이벤트가 발생한 상태
- Background: 앱이 백그라운드에 있는 상태. 그러나 실행되는 쓰레드가 있는 상태
- Suspended: 앱이 백그라운드에 있고, 실행되는 쓰레드가 없는 상태
앱의 생명주기의 컨셉 이해하기 (정확하게 말하면 예전 버전 - Scene 도입 전 / iOS 12까지)
이러한 생명주기는 AppDelegate.swift 파일에서 모든 것을 관리했다.
그래서 AppDelegate.swift 파일에서 이러한 앱 생명주기 즉 앱의 시점들을 관리하는 메서드들을 iOS 12 버전 전까지는 모두 포함하여 관리하고 있었다.
//
// AppDelegate.swift
//
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application 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.
// 새로운 장면 세션이 생성될 때 호출됩니다.
// 이 메서드를 사용하여 새 장면을 만드는 데 사용할 구성을 선택합니다.
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.
// 사용자가 장면 세션을 버릴 때 호출됩니다.
// 애플리케이션이 실행되지 않는 동안 세션이 삭제된 경우 이는 application:didFinishLaunchingWithOptions 직후에 호출됩니다.
// 이 메서드를 사용하여 폐기된 장면과 관련된 모든 리소스는 반환되지 않으므로 해제합니다.
}
}
하지만
https://developer.apple.com/videos/play/wwdc2019/258/
//
// SceneDelegate.swift
// MemoStudyApp
//
//
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
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).
// 이 메서드를 사용하여 UIWindow `window`를 제공된 UIWindowScene `scene`에 선택적으로 구성하고 연결합니다.
// 스토리보드를 사용하는 경우 `window` 속성이 자동으로 초기화되고 장면에 연결됩니다.
// 이 대리자는 연결 장면이나 세션이 새 것임을 의미하지 않습니다(대신 `application:configurationForConnectingSceneSession` 참조).
guard let _ = (scene as? UIWindowScene) else { return }
}
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).
// 장면이 시스템에 의해 해제될 때 호출됩니다.
// 이것은 장면이 배경에 들어간 직후 또는 해당 세션이 삭제될 때 발생합니다.
// 다음에 장면이 연결될 때 다시 만들 수 있는 이 장면과 관련된 모든 리소스를 해제합니다.
// 장면은 세션이 반드시 폐기되지 않았기 때문에 나중에 다시 연결할 수 있습니다(대신 `application:didDiscardSceneSessions` 참조).
}
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.
// 장면이 비활성 상태에서 활성 상태로 이동할 때 호출됩니다.
// 장면이 비활성 상태일 때 일시 중지된(또는 아직 시작되지 않은) 모든 작업을 다시 시작하려면 이 메서드를 사용합니다.
}
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).
// 장면이 활성 상태에서 비활성 상태로 이동할 때 호출됩니다.
// 일시적인 중단(예: 수신 전화)으로 인해 발생할 수 있습니다.
}
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.
// 장면이 배경에서 전경으로 전환될 때 호출됩니다.
// 이 메서드를 사용하여 배경 진입 시 변경 사항을 취소합니다.
}
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.
// 장면이 전경에서 배경으로 전환될 때 호출됩니다.
// 이 방법을 사용하여 데이터를 저장하고, 공유 리소스를 해제하고, 충분한 장면별 상태 정보를 저장합니다.
// 장면을 현재 상태로 되돌립니다.
}
}
다시말해 기존 에 AppDelegate.swift 파일에서 앱 생명주기를 전부 관리하다가
SceneDelegate.swift 파일과 역할을 분담하여 메서드들을 나눈 것이다
빨간색 점이 AppDelegate.swift에 존재하는 메서드
파란색 점이 SceneDelegate.swift에 존재하는 메서드이다 .
사실상 앱을 OS 내부적으로 살리고 죽이는 시점에 대한 메서드들이 AppDelegate.swift 파일에서 존재하고
Scene의 전환이 일어나는 Foreground(Inactive, Active) / Background 메서드들이 SceneDelegate.swift 파일에 존재한다.
그리고 이름 그대로 델리게이트 패턴을 사용하기 때문에 내부 메커니즘을 완벽하게 파악하지 않아도 상관 없고(파악하려고 해도 애플의 자산이라 비공계 자료이다.)
우리는 그냥 필요한 시점에 구현만 하면된다.
참고 자료들
https://velog.io/@bsm4045/iOS-%EB%A9%B4%EC%A0%91%EC%A7%88%EB%AC%B8-%EA%B3%B5%EB%B6%80-...-ing