🍎 iOS/iOS 기본 & UIKit

[iOS] AppDelegate, SceneDelegate (+UIWindow, UIScene, UIWindowScene)

dev_zoe 2021. 9. 7. 00:21
반응형

iOS 생명주기의 변화 (WWDC 19)

iOS 12버전 이전

iOS의 App Delegate에서 lifecycle은 2가지로 나뉨

- Process Lifecycle : process 수준에서의 event를 알려줌 -> process가 실행되려고 하는지 종료하려고 하는지에 대한 정보

- UI Lifecycle : UI의 상태를 알려줌 -> 포그라운드에 있는지, 액티브 상태인지, 백그라운드 상태 인지 ...

 

이 당시에는 앱은 하나의 프로세스와 하나의 UI 상태만 존재했기에 이 구조가 가능했다.

iOS 13버전 이후 (multi window가 지원되기 시작한 이후)

iOS 13 버전에서 멀티 윈도우를 지원하면서 (즉 1개 이상 다수의 UI나 Scene session들을 가지게 되면서 이 각각에 대한 생명주기를 관리할 필요가 있어졌다.)

 

* 여기서의 윈도우란 무엇이고, 멀티 윈도우는 뭐고 Scene은 뭐고 Scene Session은 뭔지 갑자기 모르는 용어들이 등장해서 찾아보았다.

 

0) iOS의 UI 구조

 

1) UIWindowScene

https://developer.apple.com/documentation/uikit/uiwindowscene

 

UIWindowScene | Apple Developer Documentation

A scene that manages one or more windows for your app.

developer.apple.com

- 1개 이상의 윈도우를 포함한 UI의 인스턴스를 관리한다.

- scene의 상태가 변경되면, UIWindowSceneDelegate에 알려주게 되고, 해당 delegate는 상태에 맞는 동작을 실행하게 된다.

 

2) UIWindow

https://developer.apple.com/documentation/uikit/uiwindow

 

UIWindow | Apple Developer Documentation

The backdrop for your app’s user interface and the object that dispatches events to your views.

developer.apple.com

- 앱 UI의 배경(backdrop) 이며, 뷰에 이벤트를 보내는 (dispatch) 객체이다.

- 앱의 컨텐츠를 보여주기 위한 메인 윈도우 제공 (스토리보드를 사용한다면 메인 윈도우는 자동으로 생성되며, 스토리보드를 사용하지 않고 코드로 UI를 짠다면 윈도우를 별도로 생성해야한다.)

- 윈도우는 어떤 시각적인 모습은 없지만, 1개 이상의 뷰들을 가지고 있으며 루트 뷰컨트롤러를 통해 뷰를 관리한다.

 

3) UIScene

https://developer.apple.com/documentation/uikit/uiscene

 

UIScene | Apple Developer Documentation

An object that represents one instance of your app’s user interface.

developer.apple.com

- 각 앱의 인스턴스에는 각각의 scene 이 생성된다.

- UIKit은 보통 UIWindowScene 오브젝트를 생성하지만 정보 접근이나 메소드를 사용하고자 할 때에는 UIScene을 사용하게 된다.

- UIScene이 곧 UIWindow의 인스턴스화 된 모습 (UIWindow가 액자이고 UIScene이 그림이라고 생각하면 쉬움)

 

이 사진으로 정리하면 1개의 메모앱에 2개의 UIWindowScene이 있는 것이고, UIWindowScene은 각각의 Window+Scene을 총체적으로 관리하는 매니저 역할을 한다.

 

따라서 SceneDelegate 파일을 보면 UIWindowSceneDelegate를 위임받아서 각 UIScene을 관리한다.

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).
        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).
    }

    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.
    }


}

 

즉, 여기까지 다시 정리해보자면

멀티 윈도우라는 개념이 iOS 13 이후 등장하게 되면서

멀티 윈도우라는 것은 곧 하나의 앱에 여러 윈도우와 씬을 가질 수 있게 되었기 때문에, 이 각각의 상태를 관리할 존재가 필요하게 되었기 떄문에 SceneDelegate 라는 개념이 생겨나게 된것이다.

 

Scene Delegate는 언제 쓸까?

  • scene의 not running, inactive, active, background, suspend 등의 UI lifecycle 관리
  • 메인 윈도우의 root ViewController 관리 (가장 먼저 보여줄 ViewController)

App Delegate는 언제 쓸까?

  • 앱의 중앙 데이터 구조를 초기화
  • 앱의 scene을 구성(Configuration)
  •  밖에서 발생한 알림(배터리 부족, 다운로드 완료 등)에 대응
  • 앱의 scenes, views, view controllers에 한정 되지 않고 앱 스스로를 타겟하는 이벤트에 대응
  • 푸쉬 알림이나 Firebase, 소셜 로그인 등과 같이 앱이 시작할 때(런칭할 때) 요구되는 모든 서비스를 등록

App LifeCycle & Scene LifeCycle

 

생명주기는 따로 포스팅해두었다. 링크 이동

 

 

Reference

https://velog.io/@minni/Architecting-your-app-for-multiple-windows

 

Architecting your app for multiple windows

WWDC 2019 Architecting your app for multiple window 영상에 대해서 알아보자!

velog.io

https://sihyungyou.github.io/iOS-lifecycle/

 

iOS) 앱/Scene 생명주기

App/Scene Life Cycle

sihyungyou.github.io

 

반응형