iOS/iOS 지식

[iOS] AppDelegate & SceneDelegate

홍복치 2024. 5. 18. 13:55

AppDelegate의 주된 역할(iOS13이전)

1. Process LifeCycle

프로세스 레벨의 앱의 이벤트를 알림

시스템은 프로세스가 런칭(App Lanched)되거나 전환(App Terminated)될 때 AppDelegate에게 알려줌

 

2. UI LifeCycle

앱의 UI 상태에 대해 알림( Enter ForeGround, Became Active 등 )

 

AppDelegate를 사용해도 괜찮았던 이유

앱이 하나의 프로세스, 그에 맞는 하나의 유저 인터페이스를 가지고 있기 때문

=> 즉, 멀티 윈도우의 사용이 불가했기 때문

AppDelegate의 didFinishLaunchingWithOptions에서 아래와 같은 처리를 할 수 있음

1. non-UI global setup(데이터베이스 연결, 데이터 초기화 등)

2. UI setup

 

iOS13부터 SceneDelegate를 사용하게 된 이유

앱들이 하나의 프로세스를 공유하며 여러 UI, Scene Session 갖게 되었기 때문

iPadOS등장과 멀티 윈도우 지원을 통해 여러 scene을 관리해야 할 필요가 생김

 

AppDelegate의 역할변화와 SceneDelegate

 

AppDelegate: Process LifeCycle(프로세스 이벤트, 생명주기), Session LifeCycle 을 관리

SceneDelegate: UI LifeCycle 관리

 

AppDelegate에서 UI Lifecycle에 대한 관리를 더이상 하지 않고 SceneDelegate에서만 관리

AppDelegate에 session에 대한 관리가 추가(새로운 scene의 session이 생성되거나 기존에 있던 scene session이 없어질 때)

 UIWindowScene, UIWindow, SceneSession

여기서 알고 가야할 기본적인 개념에 대해서 추가로 알아봄

앱은 여러개의 scene을 가질 수 있고, 그 scene에서 또 여러개의 window를 가질 수 있음

같은 앱이어도, 여러 화면을 띄울 수 있는데 그 각각의 화면이 각각의 scene임

 

UIWindowScene 

앱에 대한 하나 이상의 window를 관리

UIScene를 상속받고 있음

용자와  상호 작용할 때 해당 scene의 수명 주기를  관리함 

 

UIWindow

scene과 연결되어 있으며 UI의 배경이자 뷰에 이벤트를 전송하는 객체임

UIView의 하위 클래스이므로 Window는 그 자체가 view임(액자 느낌임)

keyWindow: scene과 연결된 window

(여러 window가 존재한다면 keyWindow를 설정해서 현재 scene에 보여지는 화면을 설정할 수 있음)

 

UISceneSession

사용자가 앱에 새 장면을 추가하거나 요청하면 시스템은 해당 장면을 추적하기 위해 session 개체를 생성

session에는 고유한 식별자와 scene의 구성 세부사항(configuration details)가 들어 있음

UIKit은 session 정보를 scene의 생애 동안 유지하고 사용자가 그 scene을 스위처에서 닫으면 그 session을 파괴함

iOS13에서의 Lifecycle

실제 UI Scene을 생성하기 전에 AppDelegate에서 didFinishLauching, configurationForSession을 호출

 

didFinishLaunching

- UI가 아닌 일회성 설정

configurationForSession

- scene을 생성하기 전에 호출

- 위에서 새로운 scene을 생성할 경우 session도 함께 생성된다고 한 연장선임

- configuration(구성)에 대해 설정. info.plist에서 정의 하거나 코드로 정의할 수 있음

앱이 런칭되고 scene session도 생성되었는데 UI를 볼 수 없음 → sceneDelegate에서 scene session에 연결 필요

 

wilConnectTo session

UIWindow 설정(설정 시 userActivity나 stateRestorationActivity 확인 필요)

 

유저가 스와이프해서 홈으로 돌아간 경우

SceneDelegate의 sceneWillResignActive, sceneDidEnterBackground ----> sceneDidDisconnect 호출

 

sceneDidDisconnect

앱 스위처에서 날렸을 때 background로 가는데, 이 때 시스템이 자원확보 목적으로 메모리에서 할당 해제가 될 수 있음

scene이 해제되면 윈도우 계층, 뷰계층도 해제됨

유의해할 점은 이 곳에서 유저데이터나 상태에 대한 영구적 삭제를 하면 안되는데, scene이 다시 재연결 또는 반환될  수 있기 때문임

 

앱 스위쳐로 앱을 종료시킨 경우

AppDelegate의 didDiscardSceneSessions 호출

 

didDiscardSceneSessions

scene과 관련된 사용자 상태 또는 데이터(텍스트 에디터 앱에서 저장되지 않은 작업물 등)에 대해 영구적으로 위임할 수 있음

앱의 프로세스가 실행되지 않는 동안 스위쳐에서 앱을 제거할 수 있는데 

프로세스가 실행되지 않은 경우 시스템에서 폐기된 session을 추적하고 다음 실행이후 이를 호출함

(앱을 날렸을 때 뿐 아니라 다음 실행에서도 불릴 수 있다는 소리임)

실질적으로 리소스를 해지할 수 있음

 

iOS버전에 따른 SceneDelegate의 사용

If you enable scene support in your app, iOS always uses your scene delegates in iOS 13 and later. In iOS 12 and earlier, the system uses your app delegate.
Scene support is an opt-in feature. To enable basic support, add the UIApplicationSceneManifest key to your app’s Info.plist file as described in Specifying the scenes your app supports.

 

공식문서에 따르면 scene 을 지원하는 앱에서는 항상 SceneDelegate를 사용한다.

iOS12와 그 이전 버전에서는 AppDelegate를 사용한다. 

scene support는 Opt-in(명시적으로 사용한다고 표시가 필요)이기 때문에 활성화 하고 싶으면 info.plist에UIApplicationSceneManifest key 를 추가하여야 한다.

Respond to scene-based life-cycle events

scene별로 별도의 생명주기를 가짐

하나의 앱은 여러 scene을 가질 수 있으며 이를 개별적으로 띄우고 숨길 수 있음

 

scene의 생명주기- InActive, Active, Background, Suspend

1. 새로운 scene에 대한 요청이 들어오면 unattached 상태로 만듬

2. 유저가 요청한 scene은 inactive 상태로 변경되며 foreGround(화면에 보여지는 부분)로 빠르게 진입

3. inactive상태를 거쳐 active상태로 진입

4. 앱 실행도중 전화가 오거나 화면이 전환되는 이슈가 발생되면 active에서 inactive로 이동

4. 앱을 백그라운드로 보내면 inactive 상태를 거쳐 background로 이동(메모리 등의 이슈로 suspend로 진입할 수 있음)

5. 앱을 닫게 되면 suspend로 이동되며 시스템이 이를 관리

6. UIKit 은 background나 suspend상태의 scene을 회수해서 unattached 상태로 돌릴 수 있음

 

로그로 찍어본 생명주기

1) 앱을 처음 켰을 때

application(_:didFinishLaunchingWithOptions:)
scene(_:willConnectTo:options:)
sceneWillEnterForeground(_:)
sceneDidBecomeActive(_:)

 

2) 앱을 스위처로 전환할 때

전환 후 다시 앱으로 돌아옴 (inactive -> active)
sceneWillResignActive(_:) 
sceneDidBecomeActive(_:) 

전환 후 다른 앱 실행 (active -> inactive -> background)
sceneWillResignActive(_:)
sceneDidEnterBackground(_:)

제어센터, 전화 등으로 인해 화면이 전환된 경우(active -> inactive)
sceneWillResignActive(_:)

 

 

참고자료

https://developer.apple.com/videos/play/wwdc2019/258/

https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle#3200035