App essentials in SwiftUI

WWDC 2020을 통해 SwiftUI에선 AppScene 개념이 추가됐다. 이를 소개하고 있는 App essentials in SwiftUI 세션을 보고 간단히 정리해보았다.

새롭게 등장한 App, Scene 개념으로 UIKit 없이 순수 SwiftUI로만 앱을 만들 수 있게 됐다.

Views, scenes and apps

화면에 보이는 모든 뷰가 하나의 앱에 속하는 것이 아니기 때문에, 하나의 앱이 전체 화면에 대해 완벽히 제어할 수 없다. 나누어진 영역에서 앱이 보여지는 방법은 플랫폼이 제어한다. SwiftUI에선 이렇게 화면 안에 구분된 영역을 Scene이라 부른다.

윈도우는 화면에 보여지는 Scene의 컨텐츠를 보여주는 가장 흔한 방법이다. iPadOS와 같은 플랫폼은 다수의 윈도우를 나란히 보여줄 수 있다. iOS나 watchOS 그리고 tvOS는 각각의 앱에 대해서 하나의 꽉 찬 단일 윈도우를 선호한다. macOS는 Scene의 컨텐츠가 얼마나 다양한 방법으로 보여질 수 있는가를 나타내는 좋은 예다.

macOS에선 아래와 같이 다수의 윈도우로 개별 Scene을 보여주거나 탭으로 여러 Scene을 묶어 보여줄 수 있다.


이렇게 다수의 SceneApp을 구성하고 App, Scene 그리고 View는 하나의 계층 구조를 이룬다.

아래의 앱과 코드를 살펴보자.

ReadingListViewerViewScene의 한 종류인 WindowGroup에 속한다. 그리고 WindowGroupApp 프로토콜을 따르는 BookClubAppScene으로 사용된다. 코드에서 확인할 수 있는 계층구조와 우리가 위에서 살펴본 계층구조가 일치하는 것을 확인할 수 있다.

그리고 BookClubAppReadingListViewer가 선언된 코드 구조도 유사한 것을 확인할 수 있다.

  • AppView, 둘 모두 Data Dependency를 선언할 수 있다.
    • BoolClubApp - @StateObject
      • @StateObject는 이번에 새로 등장한 개념으로 이는 추후에 살펴보도록 하자
    • ReadingListViewer - @ObservedObject
  • AppView, 둘 모두 body 프로퍼티를 통해 사용자 인터페이스를 표시한다.
    • BookClubApp - var body: some Scene
    • ReadingListViewer - var body: some View

세션의 주제와 별개로 Swift 5.3부터 등장한 @main이 선언되어 있는 것을 확인할 수 있다. 이는 프로그램의 시작점을 의미한다. 기본적으로 스위프트 프로그램은 main.swift를 필요로 하는데 @main을 통해 App 프로토콜을 따르고 있는 구조체에 해당 책임을 위임할 수 있다.

Understanding Scenes

WindowGroup

WindowGroup을 통해 다수의 윈도우를 독립적으로 관리할 수 있다.

그리고 이렇게 독립된 윈도우는 서로 독립된 상태를 갖는데 이것이 SwiftUI에서 Scene의 가장 중요한 특징이라고 할 수 있다.

각각의 독립된 윈도우는 서로의 상태에 영향을 주지 않는다. App은 각 Scene이 사용할 수 있는 Shared Model을 제공할 수 있지만, 각 Scene의 뷰들의 상태는 서로 독립적이다.

그리고 위와 같이 앱 스위처에서 보여지는 타이틀을 뷰 변경자를 통해 윈도우별로 다르게 지정할 수 있다. 이는 부모 Scene의 상태에 영향을 줄 수 있는 변경자 중 하나이다.

macOS에선 WindowGroup을 사용해 아래의 기능들을 제공할 수 있다.

  • 다중 윈도우
  • 파일 메뉴에 새 윈도우 생성 메뉴 아이템 추가
    • 단축키 지원 (Command + N)
  • 윈도우 메뉴
    • 개별 윈도우를 위한 메뉴 아이템(윈도우 타이틀)
    • 다수의 윈도우를 하나의 탭 인터페이스로 통합하는 기능을 지원하는 메뉴 아이템

이 모든 것들은 부가적인 코드 없이 SwiftUI가 자동으로 지원하는 기능들이다.

Scene의 생명주기는 실행되고 있는 플랫폼에 의해 관리된다. macOS에선 새 윈도우가 필요하면 WindowGroup은 새 자식 Scene을 생성한다. 이처럼 macOS나 iPadOS와 같이 다중 윈도우를 지원하는 플랫폼에선 WindowGroup은 다수의 자식 Scene을 생성할 수 있다.

각각의 윈도우는 사용자 인터페이스 정의를 공유하지만 모두 독립된 상태를 갖는다. 그렇기 때문에 하나의 윈도우에서의 변화는 다른 윈도우에 영향을 주지 않는다.

플랫폼이 Scene 생명주기 관리에 책임이 있기 때문에, 각 뷰의 상태를 관리할 수 있는 새 프로퍼티 래퍼인 @SceneStorage라는 개념이 새로 등장했다.

이는 고유 키 값을 이용해 저장될 상태를 식별한다. 그리고 상태는 SwiftUI에 의해 적절한 타이밍에 저장되고 복원된다.

Customizing Apps

Document based App

지금까지 살펴본 BookClubApp은 Data-Driven 앱으로 Shared Model을 기반으로 하는 형태의 앱이었다.

이런 형태의 앱뿐만 아니라, 문서 기반의 앱도 존재한다. 이런 형태의 앱에선 DocumentGroup을 사용할 수 있다.

DocumentGroup은 열기, 편집, 저장과 같이 문서 기반의 앱을 관리하는데 필요한 기능을 제공하는 Scene의 한 종류다.

Preferences Window

설정 윈도우(Preferences Window)는 macOS 앱들이 제공하는 공통적인 기능 중 하나이다.

이를 위해 macOS에는 새로운 Scene 타입인 Settings 타입이 추가되었다. 이는 기본적인 설정 윈도우와 관련 단축키도 제공한다.

그리고 우린 기본 단축키 이외의 단축키도 새 변경자 API를 통해 지원할 수 있다.


해당 세션을 통해 앱과 관련하여 새로 추가된 기능 및 API들에 대해 간단히 알아볼 수 있었다. 길지 않은 세션이기 때문에 출,퇴근길에 간단하게 시청할 수 있는 세션이었다.