Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Architecting Your App for Multiple Windows #18

Open
Taehyeon-Kim opened this issue Jul 12, 2022 · 1 comment
Open

Architecting Your App for Multiple Windows #18

Taehyeon-Kim opened this issue Jul 12, 2022 · 1 comment
Assignees
Labels
UI Framework SwiftUI 및 UI Framework 카테고리 WWDC19 wwdc2019

Comments

@Taehyeon-Kim
Copy link

Dive into the details about what it means to support multitasking in iOS 13. Understand how previous best practices fit together with new ideas. Learn the nuances of structuring your application to support multiple windows, and how to instantiate your UI, handle windows coming and going, and manage your app's underlying window resources.

@Taehyeon-Kim Taehyeon-Kim added the WWDC19 wwdc2019 label Jul 12, 2022
@Taehyeon-Kim Taehyeon-Kim self-assigned this Jul 12, 2022
@Taehyeon-Kim
Copy link
Author

Taehyeon-Kim commented Jul 12, 2022

3가지 주요 토픽

  1. Changes to app lifecycle (앱 라이프 사이클의 변화)
  2. Using the scene delegate (Scene Delegate 사용)
  3. Architecture (구조 설계)

iOS 13에서 여러 창(Multiple Windows)를 사용할 수 있도록 응용 프로그램 생명 주기(App Lifecycle)의 변경 사항에 대한 개요를 살펴 보는 것부터 시작합니다. 그런 다음에 UISceneDelegate에 대해 더 깊이 파고들어 그곳에서 어떤 종류의 작업을 수행해야 하는지에 대해 이야기 합니다. 마지막으로 ArchitectureKit의 몇 가지 모범 사례를 살펴봅니다.

1️⃣ iOS 12 및 이전 버전에서의 AppDelegate의 역할과 책임

스크린샷 2022-07-12 오후 9 56 53

AppDelegate의 2가지 주요 역할

1. Process Lifecycle (프로세스 수준의 이벤트를 애플리케이션에 알리는 것)

  • 프로세스가 시작(Launching)되거나 종료(Terminate)될 때 시스템은 AppDelegate에게 알립니다.

2. UI Lifecycle

  • 애플리케이션이 UI의 상태에 대해 알도록 하게 하는 역할을 합니다.

문제의식 가져보기

스크린샷 2022-07-12 오후 10 04 27

didEnterForeground, willResignActive와 같은 메서드를 통해 시스템은 UI 상태에 대해 알게 됩니다. iOS 12와 그 이전 버전에서는 전혀 문제가 되지 않았습니다. 애플리케이션에 하나의 프로세스와 하나의 UI 인스턴스가 있기 때문입니다.

일반적으로 앱이 Launching을 마친 이후에, 해당 메서드에서 데이터베이스에 연결하거나 데이터 구조를 초기화 하는 것과 같은 one-time, non-UI (일회성, 비 UI) 전역 설정을 수행합니다. 그리고 그 이후에 UI를 설정합니다. 그러나 이것은 iOS 13에서 유효하지 않습니다.

Why?

애플리케이션은 일반적으로(그리고 아이폰에서) 하나의 프로세스를 공유하지만 여러 UI 인스턴스 또는 Scene Session을 가질 수 있기 때문입니다. iOS 13부터 아이패드에 다중 창 지원이 가능하게 되었죠. 그렇기 때문에 App Delegate의 책임이 변경되어야 했습니다.

역할의 분리

스크린샷 2022-07-12 오후 10 10 29
다음과 같이 역할이 분리되게 되었습니다.

  • AppDelegate : 프로세스 이벤트 및 생명 주기 담당, (+ 시스템이 장면 세션 생성, 삭제될 때 AppDelegate에게 알림)
  • SceneDelegate : UI 생명 주기 담당

스크린샷 2022-07-12 오후 10 12 00

AppDelegate에서 수행했던 모든 UI 설정 또는 분해(tear down) 작업은 이제 Scene Delegate의 해당 메서드로 마이그레이션 되었습니다. 실제로 iOS 13에서 애플리케이션이 새로운 Scene Lifecycle을 채택하면 UIKit은 UI 상태와 관련된 App Delegate 메서드 호출을 중지합니다. 대신에 그림에 있는 것처럼 새로운 Scene Delegate 메서드들을 호출하게 됩니다. (대부분 AppDelegate에 있던 메서드와 1:1 매핑이 됩니다.)

그렇다면 과연 iOS 13이후에서 multiple window를 지원하게 되면 iOS 12 이전 앱들은 지원을 중단해야 할까요?

걱정하지 마세요. 다시 배포를 할 때 2가지 경우의 메서드 세트를 모두 유지하면 UIKit이 알아서 런타임에 올바른 세트를 호출해줍니다.

2️⃣ Using the scene delegate (Scene Delegate 사용), App Call Stack

스크린샷 2022-07-12 오후 10 19 38

  • AppDelegate는 Option call과 함께 Launching을 마칩니다. 그리고 one-time, non-UI (일회성, 비 UI) 전역 설정을 수행합니다.

스크린샷 2022-07-12 오후 10 20 03

  • 시스템은 Scene Session(장면 세션)을 생성하게 됩니다.

스크린샷 2022-07-12 오후 10 23 16

  • 실제 UI Scene을 생성하기 전에 어플리케이션에 UIScene configuration에 대해서 물어보게 됩니다. 어떤 Scene Delegate를 사용할 것인지, 어떤 Storyboard인지 구체화합니다. Scene과 Scene subclass를 함께 생성하고 싶으면 구체화 해주면 됩니다. 이러한 Scene Configuration은 코드에서 동적으로 정의하거나 info.plist에서 정적으로 정의할 수 있습니다.

image

  • 올바른 configuration을 선택할 수 있는 기회를 제공하는데, 예를 들어 main scene configuration이 있을 수 있고, accessory scene이 있을 수 있습니다. 따라서 options 파라미터를 살펴보고 이를 컨텍스트로 사용하여 올바른 장면 구성을 선택해야 합니다. 예를 들어서 info.plist에서 이것을 정의하면 정말 간단합니다. 들어오는 Session의 역할을 전달했는지 확인하고 이름으로 참조하기만 하면 됩니다.

스크린샷 2022-07-12 오후 10 30 45

  • App이 실행되고 Scene Session을 가지게 됩니다. 그러나 아직 UI 화면은 만들어지지 않았습니다. UI를 보이게 하기 위해서는 SceneDelegate가 SceneSession을 연결하는 시점에서 설정을 해주어야 합니다.

스크린샷 2022-07-12 오후 10 34 23

  • UIWindow를 새로운 UIWindow initializer를 사용해서 설정해줍니다.
  • Window를 구성할 User Activities(유저 활동)과 State Restoration Activity(상태 복원 활동)도 확인하는 것도 중요합니다.
  • 이제 앱이 화면에 보이게 됩니다.

스크린샷 2022-07-12 오후 10 37 33

  • 만약에 사용자가 Swipe up 해서 앱을 Switcher로 보내고 홈 화면으로 돌아가게 되면 어떻게 될까요? SceneDelegate에 의해서 willResignActive와 didEnterBackground가 호출되고 그런 후에 didDisconnect가 호출됩니다. 메모리를 효율적으로 사용하기 위해 정리를 하는 과정이죠.
  • 리소스(자원)를 회수하기 위해서 Scene이 Background에 들어간 어느 시점에서 시스템은 메모리에서 해당 Scene을 할당 해제할 수 있습니다. 이는 SceneDelegate가 모든 Window(창)에서 해제되는 것을 의미하죠. 즉, Window 계층, View 계층도 모두 해제됩니다. 이렇게 하면 이 Scene과 관련된 애플리케이션의 다른 위치에서 보유하고 있던 메모리의 큰 리소스를 deallocate, release할 수 있습니다.
  • 그러나, Scene이 다시 연결되고 나중에 다시 사용될 수 있으므로 실제로 사용자 데이터 또는 상태를 영구적으로 삭제하지 않아야 합니다.

스크린샷 2022-07-12 오후 10 48 28

  • 아예 사용자가 Switcher에서 Scene을 Swipe up해서 없애는 경우에는 didDiscardSceneSessions 메서드를 호출하게 됩니다. 이 때 scene에 관련된 user state나 data를 지워주게 됩니다. 예를 들어서 텍스트 편집 상태에서 저장되지 않은 초안과 관련된 부분들을 제거해줍니다.
  • 프로세스가 Not Running 상태인 경우 시스템은 폐기된 Session을 추적하고 다음 애플리케이션이 실행될 때 이것을 불러오게 됩니다.

@Taehyeon-Kim Taehyeon-Kim added the UI Framework SwiftUI 및 UI Framework 카테고리 label Jul 12, 2022
@hyun99999 hyun99999 pinned this issue Jul 15, 2022
@Taehyeon-Kim Taehyeon-Kim unpinned this issue Jul 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
UI Framework SwiftUI 및 UI Framework 카테고리 WWDC19 wwdc2019
Projects
None yet
Development

No branches or pull requests

1 participant