본 포스팅은 Swift 5.2.4 기준으로 작성되었습니다.

SwiftUI 에서 사용자가 확인할 화면을 생성하는 것은 UIKit 과 다르게 확연히 간단해졌습니다.

첫 눈에 바로 들어오는 특징으로는 인스턴스를 생성 시에 더 이상 UI 접두사를 붙이지 않아도 된다는 것이네요. 그리고 내부적으로 바뀐 큰 차이점은 UIKit 의 인스턴스들은 대부분 class 형태로 구성되어있던 것과 다르게 SwiftUI 의 인스턴스들은 대부분 struct 형태로 구현되어있습니다.

그럼 프로젝트를 생성하고 달라진 점들을 직접 살펴보는 것이 좋겠어요. 프로젝트 생성 시 User Interface 를 SwiftUI 로 설정하고 시작하게 되면 다음과 같은 화면이 보입니다.

프로젝트를 생성하면 가장 처음 마주치는 화면

우측 상단에 위치한 Resume 버튼을 누르거나 Command + Option + P 를 누르면 SwiftUI 의 핵심기능 중 하나인 Preview 를 활성화 시킬 수 있습니다. 활성화가 정상적으로 되었다면 아이폰 화면 위에 “Hello World” 가 출력된 것을 볼 수 있습니다. 놀랍지 않나요?

기존 Storyboard 처럼 단순히 Layout 을 생성 및 확인하는 것뿐만 아니라 실시간으로 코드와 반응하며 UI 가 변화합니다. 다음 포스트에서 함께 보겠지만 심지어 버튼을 눌러 Print 까지 출력이 가능합니다. Wow

Preview 가 활성화 된 모습


View

그럼 이제 코드를 한번 살펴볼게요.

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

UIKit 과 달라도 너무 다르네요. 하지만 저는 위에서 본 Preview 의 성능에 감동을 받은 상태이니 새로운 것을 배울 마음의 준비가 되었습니다. 첫 줄을 보면 ContentView 는 View 를 상속받고 있습니다. 왠지 UIView 와 익숙할 것 같지만 혹시 모르니까 무엇인지 한번 알아보도록 하죠. Apple 공식 문서의 View

불과 3개월 전 처음 iOS 개발을 배우기 시작했을 때는 이 문서 보는게 정말 싫었습니다. 봐도 뭐가 뭔지 모르겠고 그냥 다른 블로그 찾아보는게 더 빠르고 쉬웠었거든요. 물론 지금도 이 문서 읽는 것만으로는 사용법을 완전히 익히기에는 부족하지만 그래도 모르는 것이 나타나면 일단 무조건 공식문서부터 찾아보는 습관을 들이고 있습니다. 계속 익숙해지려고 노력하니 조금씩 문서의 구성이나 읽는 방법을 알아가는 것 같아요. 좋은 iOS 개발자가 되려면 그 무엇보다 이 화면과 친해져야 할 것 같아요.

아무튼!! 충격적인게 View 가 Class 도 아니고 Struct 도 아닌 Protocol 이었어요. 아니 어떻게 Protocol 을 저런식으로 사용하지? 근데 또 곰곰히 생각해보면 ContentView 가 Struct 잖아요? 그럼 상속을 받지 못하는게 당연하니 Protocol 일 수 밖에 없었네요. UIKit 의 사용법에만 익숙한 상태라 생소하지만 아무튼 View 는 Protocol 이에요.

Protocol 을 채택했다는건 무언가 필수로 구현해야하는게 있을 수도 있다는 소리잖아요? 그게 바로 저 body 부분입니다. body 부분은 computed property 의 형태로 되어있고 some View 타입을 return 받아야 한다고 알려주고 있어요. 지금 당장 some View 가 무엇인지 전부 파헤치기는 어려우니 뭐가 되었든 View 의 종류들이면 다 괜찮아라고 이해하고 넘어갈게요.

body 의 return 값이 View 의 종류라면 괜찮다고 했는데 Text(“Hello World”) 부분이 오류가 나지않고 정상적으로 Preview 에 표시되었으니까 Text 도 View 의 일종이라는 것입니다. 확실하지 않으니까 이번에도 개발자 문서를 한번 보고 넘어가볼게요.

Apple 공식 문서의 Text

좌측 상단을 잘 보시면 Views and Controls 라고 적혀있죠? 즉 Text 는 View 나 Control 중 하나라는 뜻입니다. 그리고 설명을 보면 “A view that displays one or more lines of read-only text” 라고 명시하고 있습니다. 읽기 전용으로 쓸 수 있는 텍스트를 표시하는 View 라고 하네요. 상속을 받지도 Protocol 을 채택한 것도 아닌 것이 어떻게 View 로 구분될 수 있는건지는 잘 모르겠지만 공식 문서에서 View 라고 하니 일단 그렇게 알고 넘어가도록 합시다.


PreviewProvider

이제 두번째 문단을 살펴보도록 할게요.

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

또 생소한 것들 투성입니다. 뭔지 모르겠으니까 제일 먼저 등장하는 PreviewProvider 를 찾아봅시다.

Apple 공식 문서의 PreviewProvider 이번에도 Protocol 입니다. 어느새 조금 당연해졌죠??

Xcode 에서 previews 를 생성하는 타입이라고 하네요. 정확히는 모르겠지만 우측의 Preview 에 관여하는 코드인 것은 확실합니다. 하지만 이것만으로는 조금 부족한 것 같으니까 PreviewProvider 가 어떤 방식으로 만들어진건지 내부 코드를 봐야할 것 같아요.

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol PreviewProvider : _PreviewProvider {

    /// The type of the previews variable.
    associatedtype Previews : View

    /// Generates a collection of previews.
    ///
    /// Example:
    ///
    ///     struct MyPreviews : PreviewProvider {
    ///         static var previews: some View {
    ///             return Group {
    ///                 GreetingView("Hello"),
    ///                 GreetingView("Guten Tag"),
    ///
    ///                 ForEach(otherGreetings, id: \.self) {
    ///                     GreetingView($0)
    ///                 }
    ///             }
    ///             .previewDevice("iPhone X")
    ///         }
    ///     }
    static var previews: Self.Previews { get }

    /// Returns which platform to run the provider on.
    ///
    /// When `nil`, Xcode infers the platform based on the file the
    /// `PreviewProvider` is defined in. This should only be provided when the
    /// file is in targets that support multiple platforms.
    static var platform: PreviewPlatform? { get }
}

Property 로 previews 와 platform 을 갖고 있어요. 오늘은 충분히 많은 새로운 내용을 배웠으니 platform 은 다음에 알아보는 것으로 하고 이번에는 previews 만 살펴보도록 할게요. 사용 예시가 나와있네요.

Group 으로 View 들을 묶어 여러개를 표시할 수도 있고 .previewDevice modifier 를 사용해 표시되는 기기를 바꿔줄 수 도 있나봅니다. 이곳에 나와있지는 않지만 여러개의 previews 를 만들어 놓고 하나는 light 다른 하나는 dark 모드로 UI 를 확인해가며 작업하는 것도 가능합니다.

이렇게 SwiftUI 를 시작하는데 있어 가장 기초적인 부분들을 훑어보았는데요. 다음 포스트에서는 SwiftUI 에 여러가지 View 를 추가하는 방법을 알아보도록 하겠습니다.