iOS 개발 기록

[iOS] WidgetKit 본문

SwiftUI

[iOS] WidgetKit

택꽁이 2023. 2. 6. 13:18
728x90

WidgetKit

Date: 2022년 10월 25일
Tags: SwiftUI, WidgetKit, iOS 14.0+

WidgetKit

  • 홈 화면이나 알림센터에 배치하여 앱 정보를 표시하는 Extension
  • 위젯은 항상 최신 상태를 유지하므로 사용자가 항상 최신 정보를 살펴볼 수 있다.
  • Timeline Provider를 사용하여 구성하며, Timeline ProviderWidgetKit에게 언제 컨텐츠를 업데이트 해야하는지 알려주는 역할을 한다.
  • SwiftUI로만 사용할 수 있다.

시작하기

  • File - New - target 에서 Widget Extension을 추가한다. ( scheme active)
  • 이때 IntentConfiguration을 사용하려면 Include Configuration Intent를 체크한다.
    안하면 StaticConfiguration을 사용하게 된다.
  • 다음과 같은 에러가 생기는데 Widget 프로토콜을 SwiftUI.Widget으로 작성해준다.

  • 빌드해보면 Widget이 생성된 것을 확인할 수 있다.
  • Widget을 여러개 사용하고 싶다면 @WidgetBundleBuilder를 사용하면 된다.

Widget의 구성 요소

Configuration

  • Configuration : 위젯을 식별한다. 위젯의 content를 표시하면 View를 정의한다.
    Configuration을 초기화 하는데 필요한 파라미터들은 아래와 같다.
  • // Configuration @main struct Widget: SwiftUI.Widget { let kind: String = "Widget" var body: some WidgetConfiguration { IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in WidgetEntryView(entry: entry) } .configurationDisplayName("My Widget") // 유저가 위젯을 추가/편집 할 때에 표시되는 이름 .description("This is an example widget.") // 유저가 위젯을 추가/편집 할 떄에 표시되는 설명 .supportedFamilies([.systemSmall]) // 위젯 사이즈에 제한을 줄때 사용. 기본은 s, m , l 사이즈 } } // - 파라미터 // kind : 위젯의 식별자. String // iuntent : IntentConfiguration을 사용할 경우. // provider : TimelineProvider 프로토콜을 준수하는 객체. // Timeline은 TimelineEntry로 구성되어 위젯 업데이틀르 위한 시간을 주면 시스템이 업데이트할 날짜를 갖는다. // content : SwiftUI 로 작성한 위젯의 View

Timeline Provider

  • Timeline Provider : 시간에 따라 보여줄 업데이트할 위젯을 결정한다. Date값이 필수적임.
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []

        // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {   // btAdding값ㅣ .hour 이므로 5시간마다 위젯 뷰를 업데이트 한다.
            let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate, configuration: configuration)
            entries.append(entry)
        }

        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
  • 따라서 Widget을 업데이트 할 시간을 배열(Timeline)로 전달해야 한다.

WidgetKit (2) - TimelineEntry / TimelineProvider / TimelineReloadPolicy

  • 그런데 업데이트가 timeline에 맞춰 딱딱 업데이트 되지 않는다고 한다. 위젯이 업데이트 될 시기를 예측할 수 없으며, 업데이트 시간은 사용자에게 표시되는 빈도 등 몇가지 요인에 영향을 받는다고 한다. 원하는 시간에 업데이트 하려면 WidgetCenter API를 사용해야 한다.

SwiftUI View

  • SwiftUI View : WidgetKit에서 위젯을 표시하는데 사용하는 View.
// View
struct WidgetEntryView : View {
  var entry: Provider.Entry
  @Environment(\.widgetFamily) private var widgetFamily      // widgetFamily 프로퍼티

  var body: some View {
        // 다음과 같이 widgetFamily에 따라 뷰를 구성할 수 있다.
    switch widgetFamily {
    case .systemSmall:
      Text("smallSize")
    case .systemMedium:
      Text("mediumSize")
    case .systemLarge:
      Text("largeSize")
    @unknown default:
      Text("unknown case")
    }
  }
}

'SwiftUI' 카테고리의 다른 글

[SwiftUI]AppDelegate, SceneDelegate 만들기  (0) 2023.03.03
[SwiftUI]데이터 바인딩  (0) 2023.03.03
[iOS] swiftUI에서 UIKit 사용하기  (0) 2023.02.06
SwiftUI - View의 크기를 구하는 방법  (0) 2022.07.07
SwiftUI - Realm  (0) 2022.04.26