개발하는 동글 :]

[TIL].[iOS 앱의 생명주기 이벤트(앱 시작, 백그라운드 이동 등)를 이해하고 처리하는 방법은 무엇인가요?] 본문

카테고리 없음

[TIL].[iOS 앱의 생명주기 이벤트(앱 시작, 백그라운드 이동 등)를 이해하고 처리하는 방법은 무엇인가요?]

동글하다 2023. 10. 27. 00:26

1. 앱 실행시 발생되는 일

  • main 함수가 실행
  • main 함수는 UIApplicationMain함수를 호출
  • UIApplicationMain함수는 앱의 본체에 해당하는 객체인 UIApplication 객체를 생성한다.
  • nib파일을 사용하는 경우나, Info.plist 파일을 읽어들여 파일에 기록된 정보를 참고하여 그외에 필요한 데이터를 로드한다.
  • 앱 델리게이트 객체를 만들고 앱 객체와 연결하고 런루프를 만드는 등 실행에 필요한 준비를 한다.
  • 실행 완료를 앞두고 앱 객체가 앱 델리게이트에게 application:didFinishLaunchingWithOptions: 메시지를 보낸다.

2. 앱의 상태 변화

  • Not Running : 실행되지 않았거나, 시스템에 의해 종료된 상태
  • Inactive : 실행 중이지만 이벤트를 받고있지 않은 상태. 예를 들어, 앱 실행 중 미리 알림 또는 일정 얼럿이 화면에 덮여서 앱이 실질적으로 이벤트는 받지 못하는 상태 등을 뜻합니다.
  • Active : 어플리케이션이 실질적으로 활동하고 있는 상태.
  • Background : 백그라운드 상태에서 실질적인 동작을 하고 있는 상태. 예를 들어 백그라운드에서 음악을 실행하거나, 걸어온 길을 트래킹 하는 등의 동 뜻합니다.
  • suspended : 백그라운드 상태에서 활동을 멈춘 상태. 빠른 재실행을 위하여 메모리에 적재된 상태지만 실질적으로 동작하고 있지는 않습니다. 메모리가 부족할 때 비로소 시스템이 강제종료하게 됩니다.

3. iOS 12 이전까지의 AppDelegate

  • iOS 12 이전까지는 하나의 앱에 하나의 window
  • AppDelegate 내에서 App Life Cycle, UI Life Cycle을 모두 담당함

  • Process Lifecycle : Process 상태
  • UI Lifecycle : active, inactive, background, foreground 상태 관여

4. iOS 13 이후의 AppDelegate 와 Scene Delegate

Scene이란?

더보기
  • 사진에서 보라색 영역과 파란색 영역을 각각 하나의 Scene
  • 하나의 앱에도 여러개의 UI 인스턴스가 존재할 수 있음
  • 각 인스턴스는 UIWindowScene 객체로 관리됨
  • UIWindowScene? 
    • 앱의 scene 인스턴스 하나를 관리하는 타입으로 해당 인스턴스의 UI를 표현하기 위해 window를 갖고있다.
    • scene의 상태가 변하면 scene 객체는 UIWindowSceneDelegate 프로토콜을 채택하는 delegate 객체를 통보한다.
  • 하나의 Scene 은 앱 인스턴스의 UI 를 표현하기 위해 window, viewController 들을 포함하고 각 인스턴스에 대응되는 UIWindowSceneDelegate 객체를 가짐
  • 여러 Scene 들은 동시적으로 실행되고 하나의 앱에서 같은 메모리와 프로세스 공간을 공유한다.

같은 메모리 공간을 공유함?

두 scene에 각각 숫자를 표시하는 UILabel이 있을 때 두 변수가 동일한 메모리 공간을 차지하는 것을 의미하는 게 아니라 SceneDelegate 객체들이 App 단위의 하나의 메모리에서 나타나고 사라지는 scene lifecycle에 따라 관리된다는 것을 뜻하는 것 같다!

  • iOS 13 부터는 window 개념이 scene으로 대체되고 하나의 앱에 여러 scene을 가질 수 있게 되었음
  • UILifecycle을 더이상 ApplDelegate에서 관리하지 않음, SceneDelegate 가 이를 대체함
  • AppDelegate는 Session Lifecycle 역할을 하게 되었기에 scene session에 관련된 함수가 추가됨

5. 분할의 이유? 

  • iPad에 도입된 다중 창 지원기능이 적용된 결과입니다.그결과 AppDelegate의 작업을 두 개로 분할합니다.

6. AppDelegate

  • 앱의 가장 중요한 데이터 구조를 초기화하는 것
  • 앱의 scene을 환경설정(Configuration)하는 것
  • 앱 밖에서 발생한 알림(배터리 부족, 다운로드 완료 등)에 대응하는 것
  • 특정한 scenes, views, view controllers에 한정되지 않고 앱 자체를 타겟하는 이벤트에 대응하는 것.
  • 애플 푸쉬 알림 서비스와 같이 실행 시 요구되는 모든 서비스를 등록하는 것.
  • process변화에 호출되고 SceneDelegate는 UI적인 요소를 담당한다.

AppDelegate 메서드

//애플리케이션이 실행된 직후 사용자의 화면에 보여지기 직전에 호출
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

//애플리케이션이 최초 실행될 때 호출되는 메소드
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool

//애플리케이션이 InActive 상태로 전환되기 직전에 호출
func applicationWillResignActive(_ application: UIApplication)

//애플리케이션이 백그라운드 상태로 전환된 직후 호출
func applicationDidEnterBackground(_ application: UIApplication)

//애플리케이션이 Active 상태가 되기 직전, 화면에 보여지기 직전에 호출
func applicationWillEnterForeground(_ application: UIApplication)

//애플리케이션이 Active 상태로 전환된 직후 호출
func applicationDidBecomeActive(_ application: UIApplication)

//애플리케이션이 종료되기 직전에 호출
func applicationWillTerminate(_ application: UIApplication)

이전에는 앱이 foreground에 들어가거나 background로 이동할 때 앱의 상태를 업데이트하는 등의 앱의 주요 생명 주기 이벤트를 관리했었지만 더 이상 하지 않습니다. 하지만 푸시 알림 등록, 위치 서비스, 앱종료 등과 같은 외부 서비스는 기존과 같이 계속 처리할 수 있습니다.

7. SceneDelegate

  • 화면에 표시되는 내용(Windows 또는 Scenes)들을 처리하고 앱이 표시되는 방식을 관리

SceneDelegate 메서드

func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
 options connectionOptions: UIScene.ConnectionOptions){
    // UI창을 만들고 root view controller 를 설정하고 창으로 만듭니다.
		// 단 여기서 ViewController와 같은 클래스 객체를 만들어 사용할 때, 아직 viewDidLoad()가
		// 호출되지 않음
}
func sceneDidDisconnect(_ scene: UIScene){
 /*Scene 이 백그라운드로 갈 때 마다 iOS 는 리소스를 확보하기 위해 Scene을 삭제하는 것을 결정할 수 
있음 앱이 종료되거나 실행되지 않음을 의미하지는 않지만 scene만 세션에서 연결 해제되고 활성화되지 않는다
iOS는 사용자가 특정 scene을 다시 foreground로 가져올 때 이 scene을 scene 세션에 다시 연결하도록
결정할 수 있다 이 방법은 더 이상 사용되지 않는 리소스를 삭제하는 데 사용할 수 있다.*/
}
func sceneDidBecomeActive(_ scene: UIScene){
    // WillEnterForeground 메서드 다음에 호출된다 장면이 설정되고 표시할 준비가 되었음을 알려준다.
}
func sceneWillResignActive(_ scene: UIScene){
    // 앱이 백그라운드로 전환시 실행된다
}
func sceneWillEnterForeground(_ scene: UIScene){
    // 백그라운드에서 포그라운드로 전환시 실행
}
func sceneDidEnterBackground(_ scene: UIScene){
    // 백그라운드에서 포그라운드로 전환시 실행 sceneWillEnterForeground 이후에 실행됨.
}