WidgetKit — 무엇인가, 위젯 프레임워크 및 SwiftUI

저자: IT Sectr 게시일: 2026-06-16 읽는 시간: 9 분

WidgetKit은 iOS 14에서 도입된 Apple 프레임워크로, 개발자가 iPhone 및 iPad의 홈 화면, Mac 데스크톱, Apple Watch 페이스에 동적 위젯을 배치할 수 있게 합니다. 위젯은 앱을 열지 않고도 핵심 정보를 표시합니다 — 일기예보, 환율, 달력, 걸음 수. Apple Developer Documentation, 2026에 따르면, WidgetKit은 Apple 생태계에서 매일 최대 20억 개의 위젯 업데이트를 처리하여 시스템 화면에 정보를 표시하는 가장 많이 사용되는 프레임워크 중 하나입니다.

핵심 사항

  • WidgetKit은 iOS 14+, iPadOS 14+, macOS 11+ 및 watchOS 10+에서 SwiftUI를 통한 렌더링으로 위젯을 생성하기 위한 프레임워크입니다.
  • TimelineProvider는 TimelineEntry를 기반으로 위젯이 콘텐츠를 업데이트하는 시기와 빈도를 결정하는 프로토콜입니다.
  • WidgetFamily — 세 가지 크기(small, medium, large)로, 개발자가 각각 별도로 구성할 수 있습니다.
  • WidgetConfiguration은 위젯의 진입점으로, 구성 유형(Static, Intent, AppEntity)과 크기 패밀리를 정의합니다.
  • 제한 사항 — 위젯은 애니메이션되지 않으며, 비디오, 키보드 또는 내부 스크롤을 지원하지 않습니다.

WidgetKit이란 무엇이며 어떻게 작동하나요?

WidgetKit은 Apple 기기의 시스템 화면에 콘텐츠를 표시하는 위젯을 만들기 위한 Apple 프레임워크입니다. 위젯은 사용자가 지글 모드에서 홈 화면에 배치하는 앱의 축소 표현입니다. WidgetKit 이전에 존재했던 watchOS 컴플리케이션과 달리, 새 프레임워크는 단일 SwiftUI API를 통해 모든 Apple 플랫폼의 위젯 생성을 통합했습니다.

WidgetKit의 작동 원리는 TimelineProvider를 기반으로 합니다 — 순서가 지정된 TimelineEntry 배열을 생성하는 객체로, 각 항목에는 Snapshot(특정 시점의 위젯 특정 상태)이 포함됩니다. 시스템은 항목을 순차적으로 표시하고, 타임라인의 다음 항목으로 이동할 때 위젯을 업데이트합니다. 항목 사이에서 WidgetKit은 앱 코드를 호출하지 않습니다 — CPU 시간은 새 Timeline을 생성할 때만 소비됩니다.

WWDC 2024 세션 “WidgetKit: What’s new”에 따르면, 평균 iOS 사용자의 홈 화면에는 8~12개의 위젯이 있으며, 가장 인기 있는 카테고리는 날씨, 시간, 달력, 피트니스, 금융입니다. WidgetKit은 실시간 업데이트 대신 예약된 업데이트 덕분에 일반적인 사용 시 하루에 1% 미만의 배터리를 소모합니다.

WidgetKit과 기존 Today Extensions의 차이점

iOS 14 이전에는 위젯이 Today View로만 존재했습니다 — 첫 번째 화면에서 왼쪽으로 스와이프하여 액세스할 수 있는 패널입니다. Today Extensions에는 심각한 제한이 있었습니다: “Today” 화면에서만 사용 가능했고, 콘텐츠를 업데이트하려면 앱을 열어야 했으며, 크기 지원이 제한적이었습니다. WidgetKit은 Today Extensions를 완전히 대체하여 홈 화면, 잠금 화면(iOS 16+) 및 Mac 데스크톱에 위젯을 제공했습니다.

  • Today View뿐만 아니라 홈 화면의 위젯
  • 앱을 열지 않고 TimelineProvider를 통한 자율 업데이트
  • 하나 대신 세 가지 사전 정의된 크기
  • Smart Rotate 및 Smart Stack — 시스템에 의한 자동 위젯 순환
  • 모든 Apple 플랫폼을 위한 통합 SwiftUI API

WidgetKit 아키텍처: TimelineProvider 및 Entry

WidgetKit 아키텍처는 세 가지 주요 프로토콜로 구축됩니다: TimelineProvider, TimelineEntry, Widget. TimelineEntry는 특정 시점의 위젯 상태를 나타내는 데이터 모델입니다. TimelineProvider는 이러한 항목의 배열(Timeline)을 생성하고 각각의 활성화 날짜를 지정합니다. Widget은 공급자를 SwiftUI 뷰에 연결하는 진입점입니다.

Timeline 메서드 getTimeline은 위젯이 처음 추가될 때 시스템에 의해 호출되고 그 후 주기적으로 — 일반적으로 공급자 유형에 따라 1~6시간마다 — 호출됩니다. Timeline은 몇 시간 또는 며칠 앞의 항목을 포함할 수 있어, 위젯이 업데이트 사이에 앱 코드를 호출하지 않고 작동할 수 있습니다. 긴급 위젯 업데이트가 필요한 경우(예: 환율 변경), 앱은 WidgetCenter.shared.reloadAllTimelines()를 강제로 호출할 수 있습니다.

기본 TimelineProvider

swift
struct SimpleEntry: TimelineEntry {
    let date: Date
    let value: Double
}

struct Provider: TimelineProvider {
    typealias Entry = SimpleEntry
    
    func placeholder(in context: Context) -> Entry {
        Entry(date: Date(), value: 0)
    }
    
    func getSnapshot(
        in context: Context,
        completion: @escaping (Entry) -> Void
    ) {
        Entry(date: Date(), value: 42.5)
    }
    
    func getTimeline(
        in context: Context,
        completion: @escaping (Timeline<Entry>, Error?) -> Void
    ) {
        let entry = Entry(date: Date(), value: fetchLatestValue())
        let nextUpdate = Calendar.current
            .date(byAdding: .hour, value: 1, to: Date())!
        let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
        completion(timeline, nil)
    }
}

Widget Family: small, medium, large

WidgetKit은 세 가지 위젯 크기를 지원하며, 각각 고정된 비율을 가지고 있습니다. Small(iPhone에서 170×170 pt)은 간결한 정보를 표시합니다 — 단일 값, 아이콘 또는 짧은 텍스트. Medium(364×170 pt)은 small보다 두 배 넓으며 값 쌍 또는 미니 차트를 표시하는 데 적합합니다. Large(364×382 pt)는 세로로 화면의 거의 절반을 차지하며 테이블, 목록 또는 확장 데이터를 표시할 수 있습니다.

개발자는 최소 두 가지 크기를 지원해야 합니다 — Apple은 small + medium을 권장합니다. Large 위젯은 앱에 해당 볼륨을 채울 충분한 콘텐츠가 있는 경우에만 필요합니다. 각 크기는 자체 SwiftUI View를 가지며, WidgetKit이 시스템 화면에 렌더링합니다. 중요한 점은 WidgetKit이 사용자 정의 크기를 지원하지 않는다는 것입니다 — 세 가지 고정 크기만 지원하여 인터페이스 일관성을 보장합니다.

WidgetConfiguration을 통한 크기 구성

swift
struct WeatherWidget: Widget {
    let kind: String = "WeatherWidget"
    
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            WeatherWidgetView(entry: entry)
        }
        .configurationDisplayName("Weather")
        .description("Current temperature and forecast")
        .supportedFamilies([.systemSmall, .systemMedium])
    }
}

위젯 구성 유형: Static 및 Intent

WidgetKit은 두 가지 구성 유형을 제공합니다 — StaticConfigurationIntentConfiguration. StaticConfiguration은 모든 사용자에게 동일한 콘텐츠를 표시하는 위젯에 적합합니다: 환율, 날씨, 달력. IntentConfiguration은 사용자가 Siri 인텐트 시스템을 통해 위젯을 추가할 때 사용자 정의할 수 있게 합니다 — 예를 들어, 날씨의 특정 도시나 주식 가격의 특정 티커를 선택합니다.

IntentConfiguration은 INWidgetIntent를 사용합니다 — SiriKit의 INIntent 하위 클래스입니다. 사용자가 위젯을 추가하고 매개변수(예: 도시)를 선택하면 시스템이 이 인텐트를 저장하고 각 업데이트 시 TimelineProvider에 전달합니다. 공급자는 getTimeline 메서드에서 인텐트를 수신하고 해당 매개변수를 사용하여 콘텐츠를 구성합니다. IntentConfiguration은 Siri 및 Shortcuts와 통합되므로 개인화된 위젯에 선호되는 방식입니다.

매개변수 선택이 있는 IntentConfiguration

swift
struct WeatherWidgetEntryView: View {
    var entry: WeatherEntry
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(entry.cityName)
                .font(.caption)
                .foregroundColor(.secondary)
            Text("\(entry.temperature)°C")
                .font(.largeTitle)
        }
    }
}

struct WeatherWidget: Widget {
    var body: some WidgetConfiguration {
        IntentConfiguration(
            kind: "WeatherWidget",
            intent: WeatherConfigIntent.self,
            provider: WeatherTimelineProvider()
        ) { entry in
            WeatherWidgetEntryView(entry: entry)
        }
    }
}

SwiftUI에서 위젯 만들기: 단계별 예제

위젯 만들기는 Xcode에서 Widget Extension Target을 추가하는 것으로 시작됩니다: File → New → Target → Widget Extension. Xcode는 자동으로 TimelineEntry, TimelineProvider 및 WidgetConfiguration이 포함된 구조를 생성합니다. 개발자는 데이터를 표시하기 위한 SwiftUI View를 구현하고 올바른 업데이트 일정을 위해 공급자를 구성하기만 하면 됩니다.

아래는 현재 Bitcoin 가격을 표시하는 간단한 위젯의 전체 예제입니다: Provider는 URLSession을 통해 가격을 로드하고 시간별 업데이트로 Timeline을 생성합니다. WidgetSwiftUIView는 가격을 큰 글꼴로, 마지막 업데이트 시간을 작은 글꼴로 표시합니다.

swift
struct BTCPriceEntry: TimelineEntry {
    let date: Date
    let price: Double
    let change24h: Double
}

struct BTCWidgetEntryView: View {
    var entry: BTCPriceEntry
    
    var body: some View {
        VStack {
            Text("BTC/USD").font(.caption)
            Text("$\(entry.price, specifier: "%.0f")")
                .font(.title2).fontWeight(.bold)
            Text(entry.change24h > 0 ? "+" : "")
        }
    }
}

iOS 16+ 잠금 화면 위젯

iOS 16부터 WidgetKit은 잠금 화면 — iPhone 잠금 화면 — 지원을 확장했습니다. 잠금 화면 위젯에는 두 가지 유형이 있습니다: inline(시계 아래 한 줄 텍스트)과 rectangular(직사각형 영역). 홈 화면 위젯과 달리 잠금 화면 위젯은 더 자주 업데이트됩니다 — 시스템 트리거는 전화 잠금을 해제하지 않고 최신 정보를 표시하기 위해 15~30분마다 업데이트를 허용합니다.

잠금 화면 위젯은 accessoryFamilies와 함께 WidgetConfiguration을 통한 별도 구성이 필요합니다: accessoryCircular, accessoryRectangular, accessoryInline. 이러한 패밀리에는 엄격한 크기 및 콘텐츠 제한이 있습니다 — 이미지, 애니메이션 또는 사용자 정의 글꼴을 지원하지 않습니다. Apple은 잠금 화면 위젯에 텍스트 정보와 SF Symbols 시스템 아이콘만 사용할 것을 권장합니다.

  • accessoryCircular — 시계 아래 영역용 콤팩트 원형 위젯
  • accessoryRectangular — 시계 위 영역용 직사각형 위젯
  • accessoryInline — 시간 아래 한 줄 텍스트, 최소 크기
  • 제한 사항: 텍스트만, SF Symbols, 그라디언트; 이미지 또는 비디오 없음

WidgetKit 모범 사례 및 제한 사항

위젯을 개발할 때 WidgetKit의 제한 사항을 고려하는 것이 중요합니다. 위젯은 읽기 전용 뷰입니다: 터치 이벤트를 처리하지 않습니다(앱을 여는 탭 제외). 위젯은 애니메이션, 비디오, 키보드 입력, 스크롤 또는 대화형 요소를 지원하지 않습니다. 각 위젯은 특정 시점의 데이터 정적 스냅샷이며, 대화형 기능을 추가하려고 하면 App Store에서 앱이 거부됩니다.

모범 사례에는 강제 업데이트를 위한 Widget Center 사용, 빠른 응답을 위한 TimelineProvider 수준의 데이터 캐싱, 초기 상태를 위한 플레이스홀더 사용이 포함됩니다. 또한 여러 크기를 지원하는 것이 중요합니다 — 사용자는 위젯이 small 및 medium 변형 모두에서 사용 가능하기를 기대합니다. 부정확하거나 오래된 데이터 표시를 엄격히 피하십시오 — 사용자는 위젯의 잘못된 정보를 오래 기억합니다.

WidgetKit 제한 사항 표

허용되지 않는 것이유
애니메이션 및 비디오위젯은 정적 스냅샷입니다; 애니메이션은 배터리를 소모합니다
대화형WidgetKit은 앱 링크를 제외한 UI 요소를 지원하지 않습니다
스크롤스크롤 없는 고정 크기
키보드위젯에서 텍스트 입력이 불가능합니다
실시간 데이터데이터는 Timeline 일정에 따라 업데이트되며 실시간이 아닙니다
사용자 정의 크기small, medium, large, accessory* 고정 크기만

자주 묻는 질문

iOS와 macOS용 위젯 하나를 만들 수 있나요?

네, WidgetKit은 크로스 플랫폼입니다. 동일한 Widget Extension을 단일 SwiftUI 코드베이스로 iOS, iPadOS 및 macOS 타겟에 포함할 수 있습니다. 차이점은 지원되는 Family에서만 나타납니다 — Mac에는 accessoryRectangular가 없습니다.

WidgetKit은 얼마나 자주 위젯을 업데이트하나요?

Timeline 일정에 따라. 개발자가 다음 업데이트 시기를 결정합니다 — 1분 후 또는 하루 후. 시스템은 자주 사용되는 위젯의 업데이트를 가속화할 수도 있습니다.

위젯에 버튼을 추가할 수 있나요?

아니요, WidgetKit은 UIButton 또는 대화형 요소를 지원하지 않습니다. 유일한 작업은 위젯을 탭하여 딥 링크를 통해 앱을 여는 것입니다.

앱에서 위젯을 강제로 업데이트하려면?

WidgetCenter.shared.reloadAllTimelines() 또는 특정 위젯에 reloadTimelines(ofKind:)를 사용하세요. 앱에서 호출하면 즉시 공급자에게 새 Timeline을 요청합니다.

위젯이 배터리 수명에 영향을 미치나요?

최소한으로 — 일반적인 사용 시 하루 1% 미만의 배터리를 소모합니다. WidgetKit은 백그라운드 업데이트를 제한하고 앱을 활성 상태로 유지하지 않습니다. 주요 소비는 처음 추가할 때 Timeline을 생성하는 것입니다.

요약

  • WidgetKit은 iOS 14+, iPadOS 14+, macOS 11+ 및 watchOS 10+용 Apple 위젯 프레임워크로, 콘텐츠 표시에 SwiftUI를 사용합니다.
  • TimelineProvider는 TimelineEntry 배열을 통해 업데이트 일정을 관리하며, 각 항목은 특정 시점의 위젯 상태를 나타냅니다.
  • Widget Family에는 세 가지 크기 — small, medium, large — 와 iOS 16+ 잠금 화면용 accessory 패밀리가 포함됩니다.
  • StaticConfiguration은 사용자 간 동일한 콘텐츠에 적합하며, IntentConfiguration은 설정이 있는 개인화된 위젯에 적합합니다.
  • 위젯은 정적입니다 — 애니메이션, 대화형, 스크롤 또는 비디오 없음; 읽기 전용 데이터 표시만 가능합니다.
  • 잠금 화면 위젯(iOS 16+)은 콘텐츠 제한과 함께 accessoryCircular, accessoryRectangular 및 accessoryInline으로 제공됩니다.
  • 강제 업데이트는 WidgetCenter.shared.reloadAllTimelines()를 통해 즉시 새 Timeline을 요청할 수 있습니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기