티스토리 뷰

iOS

[iOS] AppDelegate와 SceneDelegate

Kim_Baechu 2021. 1. 4. 22:33

iOS 13이 나오면서 SceneDelegate가 나왔습니다.

그전에는 AppDelegate를 사용했는데 어떤 점이 달라졌는지 알아보겠습니다.

 

자료를 찾다보면 SceneDelegate를 삭제하고 AppDelegate만 사용하시는 분들이 있는데, iOS13 이상 지원하는 앱이라면 SceneDelegate를 사용하는게 애플의 방향성과 일치하지 않을까 라는 생각을 합니다.

 

iOS 12 이하에서 App Delegate 살펴보기

App Delegate는 두가지 중요한 역할을 합니다.

 

첫 번째는 시스템의 프로세스 수준의 이벤트를 알리는 것입니다.

앱이 실행되거나 꺼지거나 할 때 시스템은 App Delegate로 알립니다.

 

두 번째는 UI의 상태를 알려주는 것입니다.

Entered Foreground 처럼 UI상태를 알려줍니다.

 

iOS12에서는 하나의 프로세스와 하나의 유저 인터페이스 인스턴스만 가지고 있어서 괜찮았습니다.

 

앱 델리게이트는 이런 식으로 사용되는 데

1. 데이터베이스에 연결하거나 데이터 structure를 구조화 하는 것처럼 UI와 관련없는 최초 글로벌 설정과 2. 유저인터페이스 이렇게 크게 두 개를 지정합니다.

이게 iOS12에서는 괜찮은데 iOS13에서는 안됩니다. 

왜냐하면 이제 앱이 하나의 프로세스를 공유하면서 여러개의 UI 인스턴스나 씬 세션을 가지고 있을 수 있기 때문입니다.

App Delegate가 조금 바뀌어야겠죠.

 

App Delegate는 여전히 프로세스 이벤트와 라이프사이클을 책임지지만 UI라이프 사이클은 아닙니다.

대신 이렇게 Scene Delegate가 생겼습니다.

만약에 앱이 iOS13 이상에서 새로운 씬 라이프사이클을 적용하면, UIKit은 오래된 App Delegate UI상태관련 메서드를 호출하지 않습니다.

 

 

대신에 이렇게 1:1로 매칭되는 새로운 메서드를 Scene Delegate에서 사용할 수 있습니다.

iOS13 에서 멀티 윈도우를 사용한다고 iOS 12이전 버전 지원을 중단할 필요는 없습니다.

재배포 한다면(back deploying) App Delegate와 Scene Delegate을 둘다 가지고 있으면 UIKit이 알아서 정확하게 작동하기 때문입니다.

 

App Delegate에 추가된 게 있습니다.

새로운 씬 세션이 생성되거나 이미 존재하는 씬이 버려질 때 알려줍니다.

 

 

 

이 파란 앱을 처음 실행했을 때를 보죠.

먼저 didFinishLaunching이 불리는데 여기서 UI와 관련되지 않은 일회성 설정을 할 수 있겠죠.

그 다음에 즉시 scene 세션을 만듭니다.

하지만 실제 UI 씬을 만들기 전에 UIScene configuration에 대해 앱에 요청합니다.

 

 

여기서 씬 델리게이트, 스토리보드, 씬이랑 같이 만들 서브클래스 씬을 정할 수 있습니다.

이러한 씬 구성을 코드에서 동적으로 정의하거나 info.plist에서 정적으로 정의할 수 있습니다.

이렇게 해서 올바른 구성을 선택할 수 있습니다.

main scene이나 accessory scene 구성이 있겠죠.

따라서 여기에 제공된 옵션 파라미터를  context로 사용하여 올바른 씬 구성을 선택해야합니다. 

info.plist에서 정의하면 매우 간단합니다.

AppDelegate에 이렇게 되어있는데 SceneSession을 사용할 때 다시 한번 봐야겠습니다.

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

 

앱이 실행되었고 Scene session(씬 세션)을 가지고 있습니다.

하지만 UI는 하나도 안보이고 여기서 Scene Delegate에 didConnectToSession이 나오네요.

 

여기서 새로 지정된 UI window initializer를 사용해서 UIWindow를 설정할 수 있습니다.

관련된 user activitites와 state restoration activities도 윈도우를 설정하기 위해서 같이 체크해야합니다.

 

실제 SceneDelegate에는 이렇게 나오네요.

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

 

 

스와이프 업해서 홈으로 가면 Scene Delegate에서 resign active와 didEnterBackground가 호출됩니다.

시간이 지나면 씬의 연결이 끊길 수 있는데요.

백그라운드로 가면 리소스를 회수하기 위해서 시스템에서 메모리에서 씬을 해제합니다.

 

(아이폰은 특히 램이 타 스마트폰에 비해 적은데, 그래서 연식이 좀 되는 (아이폰 8 같은) 아이폰은 앱 리프레시가 엄청 잘 되는데 이거랑 관련이 있어 보입니다.)

 

윈도우 계층구조랑 뷰 계층구조에서 잡고있던 씬도 다 해제된다고 합니다.

 

그런데 여기서 유저데이터나 상태를 영구히 삭제하면 안됩니다. 왜냐면 나중에 다시 연결될 수 있기 때문이에요.

뭔 말이냐면, 무조건 disconnected되는건 아니니까 여기서 데이터 삭제같은 중요한 일을 하지말라~ 

 

 

만약에 유저가 실제로 앱을 꺼버린다면 어떻게 될까요?

그러면 시스템은 didDiscardSceneSession을 호출합니다.

여기서 유저 상태나 데이터 관련된 일을 처리할 수 있겠죠.

(뭐 예를 들어서 메모를 쓰다가 강제종료를 했을 때 지금까지 쓴걸 자동저장하거나 삭제하거나 그런??)

이게 실제 앱 프로세스가 실행 중이 아닌 동안 스와이프 업 해서 제거하면 삭제된 세션을 추적해서 다음 실행 직후에 호출한다고 합니다.

이 부분은 신기하네요.

 

 

 

WWDC - Architecting Your App for Multiple Windows 참고

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

 

Architecting Your App for Multiple Windows - WWDC 2019 - Videos - Apple Developer

Dive into the details about what it means to support multitasking in iOS 13. Understand how previous best practices fit together with new...

developer.apple.com

 

 

댓글
공지사항