ios

[ios - SwiftUI] Widget 사용하기 (1/2)

POKY_0908 2021. 2. 4. 10:23

 

 

이번 글에서는 위젯 사용 및 뷰 이동을 테스트한 글을 정리해 보았습니다.

 

먼저 Swift 프로젝트에서 Widget Extension을 추가해 주도록 하겠습니다.

 

Include Configuration Intent 체크 여부에 따라  IntentConfiguration,  StaticConfiguration 결정 

 

 

Extension이 추가되면 기본적인 코드가 작성된 swift 파일을 확인할 수 있습니다.

 

이제 작성된 코드의 의미를 먼저 알아보도록 하겠습니다.

 

struct Provider: IntentTimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(), configuration: ConfigurationIntent())
    }

    func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(), configuration: configuration)
        completion(entry)
    }

    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 {
            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)
    }
}

 

Provider : 위젯을 렌더링 할 시기를 알려줍니다.

 

getSnapshot : WidgetKit이 현재 상태를 나타내는 스냅샷을 요청합니다.

위젯 갤러리에서 위젯을 표시할 때 위젯의 현재 상태나 몇 초 이상 걸릴 수 있는 작업에 대한 샘플을 나타내 준다고 합니다.

 

getTimeline  : WidgetKit이 현재 상태 및 상태가 변경될 미래 날짜 포함된 타임 라인 엔트리 배열 요청이라고 되어있는데

그냥 위젯에 대한 작업을 처리할 시간 배열입니다. 해당 시간이 경과할 때 뷰를 바꿔주며 이 시간은 시스템 시간과는 다릅니다.  

 

 

WidgetKit 역할

위젯을 업데이트할 Date 배열을 TimeLine 이라고 하는데 이것을 Webkit에게 전달하고 뷰가 교체될 때의 로딩을 방지합니다.

 

 

 

TimeLine 처리

WidgetKit은 TimeLine을 전달 받은 후 해당 시간에 뷰를 렌더링 해줍니다. 전달받은  배열이 마지막이라면 다시 한번 타임라인을 요청하도록 합니다.

 

 

 

struct SimpleEntry: TimelineEntry {
    let date: Date
}

struct myWidgetEntryView : View {
    var entry: Provider.Entry
    var body: some View {
        Text(entry.date, style: .time)
    }
}

@main
struct myWidget: Widget {
    let kind: String = "myWidget"
    var body: some WidgetConfiguration {
        IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
            myWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
    }
}

struct myWidget_Previews: PreviewProvider {
    static var previews: some View {
        myWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent()))
            .previewContext(WidgetPreviewContext(family: .systemSmall))
    }
}

kind : 위젯을 식별할 수 있는 문자열

body : 위젯의 내용을 나타냄

IntentConfiguration : 사용자가 위젯의 프로퍼티를 수정할 수 있다.

StaticConfiguration :  사용자가 위젯의 프로퍼티를 수정할 수 없다.

PreviewProvider : 위젯을 추가할때 미리 보기

 

 

 

 

 

홈 화면에서 기본적으로 위젯을 추가할 수 있습니다.