Post

Swift 위젯의 구조

Swift 위젯의 구조

Swift 위젯의 구조: Provider와 생성자의 이해

iOS 14부터 애플은 홈 화면에 위젯을 배치할 수 있도록 WidgetKit을 도입했다. SwiftUI 기반으로 작성되는 위젯은 앱과는 다른 생명주기와 구조를 가진다. 이 글에서는 위젯을 구성하는 핵심 구조인 Provider, 그리고 위젯에서 종종 만나는 생성자 규칙에 대해 다룬다.


위젯의 핵심 구조: TimelineProvider

Swift 위젯은 기본적으로 TimelineProvider라는 프로토콜을 채택한 구조체를 통해 데이터를 관리한다. 이 구조체는 총 3개의 필수 메서드를 구현해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
struct MyWidgetProvider: TimelineProvider {
    func placeholder(in context: Context) -> Entry {
        // 위젯이 처음 로드될 때 사용할 더미 데이터
    }

    func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
        // 위젯 갤러리에서 보여줄 미리보기
    }

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
        // 실제 위젯에 표시될 데이터와 업데이트 주기를 정의
    }
}

각 함수의 역할을 구체적으로 보면 다음과 같다.


1. placeholder()

  • 위젯이 로딩 중일 때 표시할 더미 데이터를 제공한다.
  • 네트워크 요청 전에 기본 레이아웃이나 틀을 잡아주는 용도.
1
2
3
func placeholder(in context: Context) -> MyEntry {
    MyEntry(date: Date(), title: "로딩 중...")
}

2. getSnapshot()

  • 위젯 갤러리에서 사용자에게 보여주는 “미리보기”를 구성한다.
  • 네트워크 통신 없이 간단한 예시 데이터를 보여줄 수 있도록 설계한다.
1
2
3
4
func getSnapshot(in context: Context, completion: @escaping (MyEntry) -> Void) {
    let entry = MyEntry(date: Date(), title: "예시 데이터")
    completion(entry)
}

3. getTimeline()

  • 실제 위젯에서 보여줄 데이터와 업데이트 주기를 설정한다.
  • 배열 형태로 여러 개의 엔트리를 넘기며, 각 엔트리의 표시 시점을 설정할 수 있다.
1
2
3
4
5
func getTimeline(in context: Context, completion: @escaping (Timeline<MyEntry>) -> Void) {
    let entry = MyEntry(date: Date(), title: "실제 데이터")
    let timeline = Timeline(entries: [entry], policy: .after(Date().addingTimeInterval(3600)))
    completion(timeline)
}

위젯에서 생성자를 명시해야 하는 이유

Swift의 구조체나 클래스는 내부에서 사용할 때는 암시적 생성자를 자동으로 제공한다. 하지만 위젯은 Entry를 외부에서 선언하고 전달하는 구조가 많기 때문에 명시적 생성자 선언이 필요한 경우가 많다.

1
2
3
4
5
6
7
8
9
10
11
struct MyEntry: TimelineEntry {
    let date: Date
    let title: String

    // 내부에서만 사용할 경우 생략 가능하지만,
    // 외부에서 초기화해야 할 경우 명시적 생성자 작성
    init(date: Date, title: String) {
        self.date = date
        self.title = title
    }
}

주의: @AppStorage, @Environment 등 속성 래퍼를 사용하는 경우 암시적 생성자가 생성되지 않으므로 직접 작성해야 한다.


마무리

Swift 위젯은 단순한 뷰가 아닌, 시간에 따라 데이터를 갱신하는 독립적인 콘텐츠이다. TimelineProvider 구조를 이해하고, placeholder(), getSnapshot(), getTimeline() 각각의 역할을 명확히 구분할 수 있어야 위젯 개발이 가능하다. 또한, 구조체의 생성자에 대한 이해가 없으면 위젯 초기화 과정에서 막힐 수 있으니, 기본 생성자 규칙도 함께 익혀두는 것이 좋다.

This post is licensed under CC BY 4.0 by the author.