iOS

Application Life Cycle

GREEN.1229 2021. 1. 14. 19:24

안녕하세요. 그린입니다!

이번 포스팅에서는 iOS에서의 앱 생명주기에 대해 알아보겠습니다.

그리고 파생되어 AppDelegate와 SceneDelegate에 대해서도 알아보도록 하죠!

 

1. Application Life Cycle

 : iOS에서의 앱 생명주기는 아래와 같은 순서로 볼 수 있습니다.

 1) 사용자 앱 아이콘 터치 실행

 2) main() 메서드 실행 (AppDelegate 파일)

 3) UIApplicationMain 메서드 호출 실행 (앱 생명주기 단계 시작 메서드)

 4) UIApplication 객체 인스턴스 생성 (앱 로딩 프로세스)

 5) nib / Info.plist 파일에서 부가 데이터들을 Read & Load

 6) AppDelegate 객체 인스턴스 생성 > App 객체 인스턴스 연결 및 런루프 생성

 7) App 객체 인스턴스 > AppDelegate 객체 인스턴스에 application:didFinishLaunchingWithOptions: 메서드 전달

 8) 앱 실행

 

 -. @main

 : 앱의 생명주기의 처음의 스타트를 끊는 메서드

 : 스위프트 5.3 버전부터 아래와 같이 기존 @UIApplicationMain에서 @main으로 바뀌었다.

 : 해당 어노테이션을 지우면 직접 main 함수를 구현하여 앱 실행 메서드를 생성할 수 있다.

@main

 -. 앱의 5가지 상태

 1) Not Running: 종료되어있고 실행되지 않은 초기 상태

 2) Inactive: 실행되었지만 사용자의 동작을 받을 수 없는 상태

   -. 알림창을 내렸을때

   -. 앱 스위칭 할때

   -. 시스템 알림을 받을때

 3) Active: 앱이 활성화되어 실행되는 상태

 4) Background: 백그라운드에서 실행되는 상태

 5) Suspended: 백그라운드에서 정지된 상태

앱 기반 생명주기

-. Inactive와 Active 상태는 Foreground에서 작동한다.

 

-. Scene 기반 라이프 싸이클

Scene 기반 생명주기

-. 점선: 시스템(운영체제)가 관리하는 동작

-. 실선: 사용자의 액션(이벤트)에 의한 동작

 

2. AppDelegate

 : App이 해야할 일을 대신 구현해주는 Delegate를 의미한다.

 

 -. 역할

 1) Process LifeCycle

 2) Session LifeCycle

 : Scene과 세션을 연결하여 Scene 인스턴스를 관리한다. (Scene 설정)

 3) 앱의 데이터 구조를 초기화

 4) 앱의 EntryPoint(진입점)을 제공

 5) 앱 이벤트 컨트롤 (알림 등)

 

 -. 메서드

 1) application:willFinishLaunchingWithOptions: // 앱 실행 시 호출

 2) application:didFinishLaunchingWithOptions: // 앱 실행 직후 호출

 3) applicationWillTerminate: // 앱 종료 시 호출

 

3. SceneDelegate

 : iOS13 버전 이후 생겨난 Delegate 파일로 하나의 앱에 여러 Scene을 가질 수 있도록 하기 위해 만들어졌다.

   기존 AppDelegate의 UI LifeCycle의 기능을 분리시킨것으로 UI의 상태변화를 알 수 있는 역할을 한다.

 : iPad의 멀티윈도우 기능을 지원하기 위해 생겨났다.

 

-. 역할

 : UI의 생명주기 관리

 

-. 메서드

 1) EnteredForeground

: 앱이 Foreground / Background로 될 때 처리해야할 일

 -. applicationWillEnterForeground: // 앱이 Acitive 상태가 될 예정일때 호출

 -. applicationDidEnterBackground: // 앱이 백그라운드로 전환된 후 호출

 2) Became Active

 : 앱이 Active / Inactive 될 때 처리해야할 일

 -. applicationWillResignActive // 앱이 Inactive 상태 전환될 예정일때 호출

 -. applicationDidBecomeActive: // 앱이 Active 상태 전환된 후 호출

 

4. iOS 13 버전 이전과 이후

 : iOS 13 버전이 되면서 AppDelegate의 UI 생명주기 역할을 SceneDelegate에서 할 수 있도록 따로 분리시켰다.

   이전에는 하나의 앱에 하나의 Scene(Window)만 가질 수 있었는데 이후 부터는 하나의 앱에서도 여러 Scene(Window)를 지원하게 됐다.

 

-. 멀티윈도우와 멀티태스킹의 차이

 1) 멀티윈도우: 하나의 앱을 여러개 실행할 수 있는 기능으로 iPad에서 사파리 앱을 여러개 켜서 사용하는것과 같은걸 의미한다.

 2) 멀티태스킹: 여러개의 앱을 하나의 화면에서 동시에 실행하는걸 의미한다. 쉽게 생각해서 아이폰에서도 카톡을 하면서 유투브를 보는 PIP(PictureInPicture)의 기능을 생각할 수 있다.

 

!! 현재까지 멀티윈도우 기능은 아이폰에서는 되지 않고있다. 카플레이와 같이 외부 디스플레이 연결 지원의 경우는 하나의 앱을 여러 UI로 구현하는것이지 멀티윈도우 기능이 아니다.

 

iPad 체크 시 멀티윈도우 옵션 항목
iPad 체크 해제 시 사라지는 멀티윈도우 항목

위와 같이 프로젝트 General 설정에서 iPad를 체크 해제하면 멀티윈도우 지원 체크 항목이 사라지는걸 볼 수 있다.

 

-. 의문점?? 그럼 왜 iOS 아이폰 환경에서는 SceneDelegate를 사용하지도 않을것 같은데 파일이 생성되게 해놨을까?

    프로젝트 파일 생성 시 iPad 개발여부를 체크해서 아이폰에만 배포할 경우에는 SceneDelegate 대신 이전과 같은

    AppDelegate에서 모든걸 처리하게하면 안되는것인가? 그렇게된다면 iOS 13 버전 이전과 이후로 업데이트 하지 않은 기기에 대해 앱 지원도 동일하게 될것같은데 번거롭게 한 느낌이였다.

    이 의문점에 생각을 해봤는데 굳이 번거롭게 그렇게 나눌 필요가 없다는것이다. 추후 아이폰에서도 충분히 멀티윈도우를 지원할 수 있으며 SceneDelegate로 역할을 이전하여 분리시켜놔서 실제로 멀티윈도우 기능을 사용하지 않더라도 문제될게 없다.

    만약 Deployment Target이 iOS 13 이전이라면 간단하게 몇가지를 바꿔줌으로 이전과 같이 Xcode를 구성할 수 있음으로

    전혀 문제될 소지가 없다고 생각한다.

 

-. Deployment Target이 iOS 13 이전일 경우

 1) SceneDelegate.swift 파일 삭제

 2) AppDelegate의 UISceneSession 메서드 2개 삭제

    (application(_:configurationForConnecting:options:) application(_: didDiscardSceneSessions:))

 3) window 프로퍼티 AppDelegate로 이관

 4) Info.plist에서 Scene 관련 Application Scene Manifest 삭제

 

혹은 SceneDeleate파일을 삭제하지않고 iOS 13 이후 버전은 그대로 구동되고 iOS 13 이전 버전은 기존방식으로 구동되게 할때는

@available(iOS 13.0, *) 을 메서드와 클래스에 붙여주면된다.

 -> AppDelegate

 -> SceneDelegate

 

이상으로 오늘의 포스팅을 끝내겠습니다.

감사합니다!:D

 

 

[참고자료]

https://lena-chamna.netlify.app/post/appdelegate_and_scenedelegate/#AppDelegate와-SceneDelegate

https://jinshine.github.io/2018/05/28/iOS/앱의%20생명주기(App%20Life%20Cycle)와%20앱의%20구조(App%20Structure)/

http://monibu1548.github.io/2018/08/28/appdelegate/